Dynamic LINQ

Posts   
 
    
AlexWalker
User
Posts: 40
Joined: 05-Nov-2008
# Posted on: 25-Sep-2009 23:15:59   

I'm trying to come up with a solution that allows a user to pass an entity into a method and have that method build a LINQ query dynamically.

List<object> items = new List<object>();

            using (DataAccessAdapter adapter = new DataAccessAdapter())
            {
                LinqMetaData metaData = new LinqMetaData(adapter);
                var q = (from cm in metaData.ContractMaster
                         select cm)
                         .WithPath(p => p.Prefetch(cm => cm.ContractDetail));

                if (contract != null)
                {
                    IEntityField2[] fields = new IEntityField2[contract.Fields.Count];
                    contract.Fields.CopyTo(fields, 0);
                    var populatedFields = from f in fields.AsQueryable()
                                          where f.IsChanged
                                          select f;

                    foreach (IEntityField2 f in populatedFields)
                    {
                        q = q.Where(all => all.Fields[f.Name].CurrentValue.Equals(f.CurrentValue));

                    }
                }

                foreach (object o in q)
                {
                    items.Add(o);
                }
            }

My code is failing on the addition of my Where clause:

The property 'Fields' isn't mapped to a field or database construct of entity type 'ContractMasterEntity'. Did you mean to call an extension method instead? ('Count' vs. 'Count()') ?

Does anyone know how to accomplish what I'm trying to do?

Many thanks!

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 26-Sep-2009 06:04:45   

Hi Alex,

Yes, that exception is expected. Linq tries to look at "Fields" like a property queryable on the source.

I can't think right now in a workaround other than a switch in your loop.

switch (f.Name)
{
     case "FieldOne":
          q = q.Where(all => all.FieldOne == f.CurrentValue);
          break;

     case "FieldTwo":
          q = q.Where(all => all.FieldOne == f.CurrentValue);
          break;
}

(Edit) You could use LINQ2LLBL - PredicateBuilder (http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=14144&StartAtMessage=0&#78965) if you want to dynamically build the predicate. For example build it somewhere else and pass it to your method. However you can't do what you are trying to do (indexing the Fields object to point to a field).

David Elizondo | LLBLGen Support Team