I am trying to write a wrapper function for an application.
This application will continually add entities so it would be better if we could write one generic function rather than have to carve out an exception for each item.
For certain reasons we maintain both a GUID and an int key.
When an int key gets updated, we need to update it both in the parent record the child records but since it is possible that at any given time there could be multiple child records with the same int key, we need to get a list of Guids of what we want to update.
Here is some psuedo code of what I am trying to do.
List<string> depenedents = new List<string>();
depenedents.add(table1);
depenedents.add(table2);
depenedents.add(table3);
for(item in depenedents)
{
context.set<type item>();
entities.getguid();
}
Obviously the issue here is with the for loop.
Is it possible to get a list of entities knowing only the string of the entity type? Luckily all of our entities are wrapped to a base class that has a get guid method, but I need to find a way to actually get the entities.
Any help is greatly appreciated.
Something like:
for(item in depenedents)
{
context.GetMethod("Set")
.MakeGenericType(Type.GetType(item))
.Invoke(context, new object[0]);
entities.GetType.GetMethod("GetGuid").Invoke(entities, new object[0]);
}
...should be with roughly what you need. This will invoke the correct type specialisation of the Set generic instance method. Then it will invoke the instance method called "GetGuid" on the entities object.
Or possibly:
foreach(var entity in entities)
{
entity.GetType.GetMethod("GetGuid").Invoke(entities, new object[0]);
}
You'll maybe want to do something with the values returned, but hopefully this answer will point you in the right direction!
(and clearly you could optimise this code substantially to cache reflected types and methods, or to use compiled expressions rather than Invoke() calls)
Related
This question is connected (but NOT duplicate) of this one. Consider that I am fairly new to C#.
I would like, if possible, to take the handle of a member of an object that has not been instantiated jet, in order to use it later on. Following previous question, I would like to do something like
List<Action<YourClass>> lst = new List<Action<YourClass>>;
lst.Add(x => x.Member1);
lst.Add(x => x.Member2);
Member1 and Member2 are not supposed to be static member, as their value depend on the state of the object they are member of. Basically I want the handle of their "name", so that I can use it later on when the objects are instantiated. I was thinking about an approach based on string which value is the member name, but maybe there is a better way?
Thanks.
I'm not sure if i understand you right. At first you need to create an instance from your list.
List<Action<YourClass>> lst = new List<Action<YourClass>>;
Else your Add will broke with NullReference-Exception. What you are using in your Add is called anonymus function because the handle isn't saved. If you would like to store this you need a delegate. On this delegate you can call the Invoke-Methode to call it. You are allowed to create your on delegates as well as using predefined like Action.
Here is a small example without any sence, but maybe clarify:
var action = new Action<string>(x => x = x.Substring(1, 1));
//Do some other stuff
action.Invoke("Hallo");
Note that the used var keyword. It detects the result of new Action and take the type of this. In this case it holds Action.
Further note that Action is a predefined delegate. An other would be Func which got one return value. If you need other behaviour you easily can create your own delegates. For this you should read the link.
I found the solution thanks to Henk comment:
Func<myObj, Vector> getVect = new Func<myObj, Vector>
getVect= (myObj => myObj.objVector);
where objVector is NOT a method, but a member of the myObj.
I call getVect in this way:
Vector a= getVect(someObj)
Edit
To understand what i am trying to do i will give an example
Suppose you used entity framework to generate multiple tables. Now you have MyDbEntities with objects (client, user, product, singer [attributes don't matter]). Now you create a method. This method gets an object as a parameter + MyDbEntities. The object would be a client, user, product, singer. In this method you have a query that given the object would return a list of that object. I am trying to create this method but i am still trying either with linq or sql but in vain so far
Update
I tried this, it works, but not the way i want it to. to understand me check the code below.
ViewBag.ok = LibMethods.get_all(MyDbEntities, "Client"); //Params = Entity & String
this how i can my method below is my method
public static Object get_all (MyDbEntitiesce, String given_entity_type)
{
if (given_entity_type.Equals("Client"))
{
var get_all = from clt in ce.Client
select clt;
return get_all.ToList().First();
}
else if (given_entity_type.Equals("Product"))
{
var get_all = from pdt in ce.Product
select pdt;
return get_all.ToList().First();
}
return null;
}
As you can see this method checks the object given and creates and returns a list of objects of that given_entity_type. here i return the first element just because i am doing this for tests.
now suppose that i add a new object to MyDbEntities & call it Developer i would have to update that method but i don't want to do that i want something generic that would work on any object i give it that exists in MyDbEntities. that's what i mean by generic/dynamic.
Would the OfType query be what you want? I'm not sure I clearly understand your question, but this query will filter the list of objects by the given type.
Although I do not understand what your ultimate goal is, I would suggest that you look into DbSet.Set() method:
You can then use it like this Context.Set<Singer>() or Context.Set<Client>() depending on your target table.
That is the most generic you can get. Try showing more Code to make your scenario more clear.
I'm attempting to create a generic WPF form or page, that when called, will load in data from a LINQ table. Here is the concept:
I have three tables in a LINQ DataContext that are identical (apart from the data within)
TypeID and Type are the columns
I would like to generically pass that data in those tables into my second form depending on which table the user selects (essentially so they can narrow down the list of objects of said Type.
I've seen some responses, (in particular the accepted answer to this one LINQ query with a generic table) that are very close to what I am looking for, but not quite. One issue I have with the above answer is that T must be a reference type.
I've done more searching and found some more answers like:
someClass<T> : <T> where T
But unfortunately these are further from my own context and I am unable to bridge the two concepts of what is happening. Below I have posted what I hope to do.
someDataContext db = new someDataContext();
private void pageLoader<T>(){
newPage n = new newPage(T) //This is where I was hoping I could pass the table(s) to the constructor.
}
And here is the constructor:
newPage(T){
listBox l = new listBox();
l.datasource = T;
}
Any assistance in any direction would be helpful (besides MSDN, please. I've been there and I'm still lost.)
Let start from the top. LINQ is merely an abbreviation for Language Integrated Query. It is interchangeable with Lambda. Different syntax but both accomplish the same task. Querying a collection or datasource. See http://msdn.microsoft.com/en-ca/library/bb397926.aspx
You are referring to the EntityFramework Code First approach of creating a database. LINQ is merely a way to access and manipulate the information within.
With that out of the way, what you are pointing out is a Generic Method and a Generic Class. T is simply a standard naming convention for a generic type. You could use any representation you like. If you are going to be passing in entities, you might use TEntity for example.
See http://www.dotnetperls.com/generic-method
http://www.dotnetperls.com/generic
When you see someClass where T, this is a constraint for type parameters.
And finally, what you have been waiting for...
https://codereview.stackexchange.com/questions/19037/entity-framework-generic-repository-pattern
The following should put you on the right path.
http://blog.gauffin.org/2013/01/repository-pattern-done-right/ <- This would be more of a better starting tutorial
I'm new to Entity Framework (and C# for that matter) so not sure how EF all exactly works. I have it working in my code and have watched videos, but I want to do more. I'm trying to nail down the syntax and organization of my code, but I'm having trouble and would really like some help with it. I'll give you the background.
Each day I parse a text file and sometimes I will add a record to my MySQL database or sometimes update a record. There are 3 tables in the database, but may eventually grow larger. What I first did, just to get it working was create a Records class and created separate methods that would run depending on what the format of that certain section in the text file was. So for example, "A 3284712039875817230987123", would be an Address layout and the program reads the first letter, decides on the parser method to run in the Records object and runs the method. There are about 6 different parser methods, where each parse a different "layout" in the text file. Also in the Records class they each have some helper methods.
Ok, so that's the background. Now for obvious reasons you can see that this is messy. What I would like to do is essentially create an abstract parent class Records, and have its children be each layout in the text file. So have an Address layout, Data layout, which would contain their individual parser but also inherit some methods that I use over and over like adding/updating records and other ones.
The question that I have is: How do I write the formal parameters in a method so that I can pass the EntitySet and the Entity without defining the exact EntitySet and Entity type?
For example something like this:
public void AddRecord(EntitySet entitySet, Entity entity)
{
context.entitySet.Add(entity);
context.SaveChanges();
}
I'm confused on how I should construct the method. Hope this makes sense. Let me know if I need to clarify something.
thanks,
Justin
A simple method would be add those methods to your DbContext. You don't even have to supply the EntitySet, just an entity. This code doesn't take care of the parsing part.
public void AddRecord<T>(params T[] items) where T : class
{
var set = Set<T>();
foreach (var item in items)
set.Add(item);
}
A generic remove is as easy.
public void RemoveRecord<T>(params T[] items) where T : class
{
var set = Set<T>();
foreach(var item in items)
set.Remove(item);
}
Does anyone know if the following is possible to pass in a List<> of objects to a function and specify which property the function should use within each object that its working with ?
I have a class that works with a specific property of an object throughout the class, but I dont want to create multiple copies of the same class to work with different properties of that object. I thought about using Linq, but I dont see a way to specify which property to use in other functions of the manipulation class.
I was thinking there has to be a more elegant way to do this instead of creating the same class to handle each property. I thought about using Reflection to tell the function which property to work with but that gets ugly really quick
Example psuedo code :
class Store
{
int amount;
int id;
int serial;
}
class AggregationMethods
{
bool Has3Values( List<Store> places /* some other param to specify which property to use*/)
{
// do something with Store.amount or Store.id
}
// other functions to work with Store.amount or Store.id or Store.serial
}
In your case, they're all int values - so you could just retain a Func<Store, int> or pass it into each method. It becomes slightly harder if you need to work over multiple types, but we don't really have enough information to comment further.
It's also not clear whether you would expect two have multiple instances of AggregationMethods (e.g. one for amounts, one for IDs etc) or whether these would really be static methods. If you're using instances, then you could keep the projection as a member variable, and apply it within each method.
It's worth noting that the properties you've given probably don't really make sense to apply the same aggregations - for example, while summing amounts makes sense, it's meaningless to sum IDs.