Click here to Skip to main content
15,888,351 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
foreach (var item in ListOfevents)
{
var query = Globals.db1.events.Where(p => p.ID == item.ID);
dosomething(query);
}


i want to find out, if some row of type "events" with some PrimaryKey exists in
the database or not.If you know the type at designtime it would be really easy.
But i want to try it a bit dynamic. I tried to accomplish that with expression trees. The code below works, but i cant do that totally dynamic.
How i Can replace the 2 Types "events" to something dynamic, in the 2 lines below
i marked in the code?

What I have tried:

C#
private  void Query<T>(List<T> obj)
        {

            var NewObjName = (from a in Globals.db1.Mapping.GetTables()
                              where a.RowType.Name == obj.GetType().GetGenericArguments()[0].Name
                              select a).FirstOrDefault();


            Type NewObjType = NewObjName.RowType.Type;
            
            IEnumerable<object> NewIObj = obj as IEnumerable<object>;

            //Get Primary Key Field
            var NewObjPkCol = (from c in Globals.db1.Mapping.MappingSource
                              .GetModel(NewObjType)
                              .GetMetaType(NewObjType)
                              .DataMembers
                               where c.IsPrimaryKey == true
                               select c).SingleOrDefault();

                  

            foreach (var item in NewIObj)
            {
                // This Code Works, but here i want to replace >> events << Type to some dynamic
                var query = Queryable.Where(Globals.db1.events,
                    Expression.Lambda<Func<DB4880_.events, bool>>(
                        Expression.Equal(
                            Expression.MakeMemberAccess(
                                Expression.Parameter(NewObjType, "p"),
                                NewObjType.GetProperty(NewObjPkCol.Name)),
                            Expression.MakeMemberAccess(
                                Expression.Constant(item),
                                NewObjType.GetProperty(NewObjPkCol.Name))),
                        Expression.Parameter(NewObjType, "p")));

                
            }



i want to put in a list<of any table in my database>.
query each row if it exists in the database, if not i insert it.
if exists i update it with the new informations.

in my code above i tried it with a specific table called "events".

my goal would be to have ONE routine to Insert or Update any table in my database
and not for each table a routine.

private  void Query<T>(List<T> obj)
        {
 
            var NewObjName = (from a in Globals.db1.Mapping.GetTables()
                              where a.RowType.Name == obj.GetType().GetGenericArguments()[0].Name
                              select a).FirstOrDefault();
 

            Type NewObjType = NewObjName.RowType.Type;
            
            IEnumerable<object> NewIObj = obj as IEnumerable<object>;
 
           Globals.db1.GetTable(NewObjType).InsertAllOnSubmit(NewIObj);
           Globals.db1.SubmitChanges();
 
                  
 
           
 
                
            }


With that code i can Insert a List<of any="" table=""> into the database,
but if 1 row exists in the database, i get a execption or the sql server creates
a new row in case, how the Primary Key is configurated.
thats the reason why i have to find out at Runtime the primary Key of the table with code below.

var NewObjPkCol = (from c in Globals.db1.Mapping.MappingSource
                              .GetModel(NewObjType)
                              .GetMetaType(NewObjType)
                              .DataMembers
                               where c.IsPrimaryKey == true
                               select c).SingleOrDefault();


then query every row over Primary Key in the database with code Below!
you can see i used "events" (table in database) at designtime in CODE,
and that is what i want to replace with a variable that represents the
type of the table, which i want to find out at runtime.

var query = Queryable.Where(Globals.db1.events,
Expression.Lambda<func><db4880_.>events, bool>>(

Globals.db1 is my public static declaration of the database connection
DB4880_ is the namespace of the linq to sql object

foreach (var item in NewIObj)
            {
                var query = Queryable.Where(Globals.db1.events,
                    Expression.Lambda<Func<DB4880_.events, bool>>(
                        Expression.Equal(
                            Expression.MakeMemberAccess(
                                Expression.Parameter(NewObjType, "p"),
                                NewObjType.GetProperty(NewObjPkCol.Name)),
                            Expression.MakeMemberAccess(
                                Expression.Constant(item),
                                NewObjType.GetProperty(NewObjPkCol.Name))),
                        Expression.Parameter(NewObjType, "p")));
 
                
            }
Posted
Updated 20-Feb-16 13:50pm
v2
Comments
Maciej Los 19-Feb-16 10:54am    
Please, be more specific and provide more details. At this moment we don't know what you mean by saying: "i want to replace >> events << Type to some dynamic".
Sascha Lefèvre 19-Feb-16 12:40pm    
(I deleted my solution because I realized it didn't really do what you want.)

Please tell us what you want to "put in" and what you want to "get out".

 
Share this answer
 
Comments
Andreas Gieriet 21-Feb-16 4:28am    
Useful links, my 5!
Cheers
Andi
Maciej Los 21-Feb-16 4:48am    
Thank you, Andi.
Maybe this approach may help:
1) Construct a string expression based on your primary key constraint.
2) Use Invent your own Dynamic LINQ parser[^] to construct an expression tree.
3) Continue from there with applying the expression tree to your IQueryable.
Cheers
Andi
 
Share this answer
 
Comments
Maciej Los 21-Feb-16 3:54am    
Very interesting approach, Andi!
5ed!
Andreas Gieriet 21-Feb-16 4:25am    
Thanks!
Andi

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900