Print Page | Close Window

Filtering query with EntityKeyList

Printed From: IdeaBlade
Category: DevForce
Forum Name: DevForce 2010
Forum Discription: For .NET 4.0
URL: http://www.ideablade.com/forum/forum_posts.asp?TID=3186
Printed Date: 25-May-2025 at 10:21pm


Topic: Filtering query with EntityKeyList
Posted By: kpinniger
Subject: Filtering query with EntityKeyList
Date Posted: 29-Dec-2011 at 1:00pm
Our legacy database has multi part keys.  So our Customer tables primary key is CompanyCode, Division, CustomerNumber.
 
We would like to have each users query results filtered to use their "Active Customers"  so basically something like this...
 
EntityKey one = new EntityKey(typeof(Customer), new [] {"1", "US", "A100"});
EntityKey two = new EntityKey(typeof(Customer), new [] {"1", "US", "C100"});
EntityKey three = new EntityKey(typeof(Customer), new[] { "1", "WW", "I-A100" });
EntityKey four = new EntityKey(typeof(Customer), new[] { "1", "WW", "I-D100" });
EntityKeyList myCustomerList = new EntityKeyList(typeof(Customer), new[] { one, two, three, four });
 
So then when I am querying against another table like ArTransactions that has CompanyCode, Division, and CustomerNumber in the table I would like to limit the results of select all ArTransactions to this list of Customers above.
 
Ideally I would like to do something like this in my repository
 
            return from art in myEntityManager.ArTransactions
                   where myCustomerList.Contains(new { CompanyCode = art.CompanyCode, Division = art.Division, CustomerNumber = art.CustomerNumber })
                             select art;
 
or even something like this
 
            var entityQuery = myCustomerList.ToQuery();
            var myActiveCustomers = myEntityManager.ExecuteQuery(entityQuery).Cast<Customer>();
            return from art in myEntityManager.ArTransactions
                   join actCust in myActiveCustomers
                           on new { art.CompanyCode, art.Division, art.CustomerNumber } equals
                              new { actCust.CompanyCode, actCust.Division, actCust.CustomerNumber }
                   select art;
 
Anyone have any ideas on how to do this?



Replies:
Posted By: kimj
Date Posted: 29-Dec-2011 at 5:12pm
That's a tough one.  Since the "contains" is essentially an OR of the many clauses, you could use the PredicateBuilder to build up the predicate.  It might be a bit ugly, potentially slow, and if the list is large also a potential StackOverflowException waiting to happen, but it would look something like this:
 
var predicate = PredicateBuilder.False<ArTransaction>();
foreach (var key in myCustomerList) {
   var code = (int)key.Values[0];
   var division = (string)key.Values[1];
   var custno = (string)key.Values[2];
  
   predicate = predicate.Or(art => art.CompanyCode == code && art.Division == division && art.CustomerNumber == custno);
 }
var query = myEntityManager.ArTransactions.Where(predicate);
 
If possible, doing this filtering within a server-side EntityServerQueryInterceptor would be the best location.
 
However, I'd also possibly re-think this.  Is it possible to query for the Active Customers and use http://drc.ideablade.com/xwiki/bin/view/Documentation/include-related-entities - Includes to retrieve their transactions?  Or lazily load the transactions for a given Customer when needed? 



Print Page | Close Window