Tuesday, April 17, 2012

LINQ query for OData services for multiple tables .NET 3.5

Hi,
I faced this problem while working on LINQ to Odata services in .NET Framework 3.5. My requirement was as follows:
I've an entity say A, which contains a navigation property say B. A and B are having Many to Many relationship
For the entity B, I've another navigation property say C. B and C are having Many to Many relationship.
Now my task is how to filter A on the basis of C which is indirectly related to A. The solution is easily available for framework 4.0 but I wanted a solution for .NET 3.5 as the methods like .Any(), .Contains(), .Except() are not supported when I consume Odata service in framework 3.5.

So here's what I've figured out to complete my task:

var certList = from x in a.Expand("b/c").AsEnumerable()
                           from y in a.b
                           from z in y.c                          
where z.cID == Convert.ToInt16("3")
                           select x;

Something similar to the above query gave me the desired results.

So the whole idea here is since A contains entity B which in turns contains entity C, I need to expand both B and C.

In the above query, I took Y (entity B present in A)  and then I took Z (entity C present in B) and filtered C according to my given filter.

Hope this gives an idea about solving some of the complex queries when methods like Any(), Contains() etc. are not supported by your framework.

Cheers
Ankit

3 comments:

  1. This is the good article which can help out many people...:)

    ReplyDelete
  2. Hi,
    I have a entity say Computers with properties Dnshostname and navigation property TechnicalProductsHosted. Computers to TechnicalProductsHosted is a many to one and one to many relationship. TechnicalProductsHosted is TechnicalProducts in the odata. Entity TechnicalProducts has a navigation property ResponsibleUser with a many to one relationship. ResponsibleUser is Employees in odata. Employees has a navigation property Manager with a many to one relationship. When i click on Manager it takes me to Employee entity.I wish to get the list of manager names. I am using Linqpad. Below is the code.
    void Main()
    {
    var a = from cpuid in Computers
    where cpuid.DnsHostName == "xyz"
    select new {
    ITManager = cpuid.TechnicalProductsHosted.Select (x => x.ResponsibleUser.Manager.Select(z => new { ITManager = z.Name })),
    };
    Console.WriteLine(a);
    }
    This is the error.
    'LINQPad.User.Employee' does not contain a definition for 'Select' and no extension method 'Select' accepting a first argument of type 'LINQPad.User.Employee' could be found (press F4 to add a using directive or assembly reference)

    Please help me correct this error.

    ReplyDelete
    Replies
    1. Hi Swapnil,

      Sorry for responding late to your question. If it is still not resolved, can you please check if you are using correct spellings and correct names of entities.

      From the description, I can see you are using "Employees" while the error says the entity name is Employee.

      Also if you can post the table along with the columns, i can figure out the query and post it for you.

      Thanks
      Ankit

      Delete