views:

52

answers:

1

I'm trying to work through a problem where I'm mapping EF Entities to POCO which serve as DTO.

I have two tables within my database, say Products and Categories. A Product belongs to one category and one category may contain many Products. My EF entities are named efProduct and efCategory. Within each entity there is the proper Navigation Property between efProduct and efCategory.

My Poco objects are simple

public class Product
{
    public string Name { get; set; }
    public int ID { get; set; }
    public double Price { get; set; }
    public Category ProductType { get; set; }
}

public class Category
{
    public int ID { get; set; }
    public string Name { get; set; }
    public List<Product> products { get; set; }
}

To get a list of products I am able to do something like

    public IQueryable<Product> GetProducts()
    {
        return from p in ctx.Products
               select new Product
               {
                   ID = p.ID,
                   Name = p.Name,
                   Price = p.Price
                   ProductType = p.Category
               };
    }

However there is a type mismatch error because p.Category is of type efCategory. How can I resolve this? That is, how can I convert p.Category to type Category?

Likewise when I do

        return from c in ctx.Categories
                where c.ID == id
                select new Category
                {
                    ID = c.ID,
                    Name = c.Name,
                    ProductList = c.Products;
                };

I get a mismatch because ProductList is of type Product, where c.Products is an EntityCollection

I know in .NET EF has added support for POCO, but I'm forced to use .NET 3.5 SP1.

+3  A: 
    return from p in ctx.Products
           select new Product
           {
               ID = p.ID,
               Name = p.Name,
               Price = p.Price
               ProductType = new Category
               {
                   ID = p.Category.ID,
                   Name = p.Category.Name // etc.
               }
           };

For Category you do:

    return from c in ctx.Categories
            where c.ID == id
            select new Category
            {
                ID = c.ID,
                Name = c.Name,
                ProductList = from p in c.Products
                              select new Product
                              {
                                  ID = p.ID,
                                  Name = p.Name,
                                  Price = p.Price
                              }
            };
Craig Stuntz
Thanks! Can you give me an example on how to return Category. Here products is a List<Product> where in efCategory it is a EntityCollection<efProduct>? I updated the question to reflect this.
Scott
OK; I added an example for that.
Craig Stuntz
But what if i want to make one place to map "Convert" the EF Model to my own Model ?. e.g. `from c in ctx.Categories select c.ToPoco();` this will work fine with L2S but not in EF cause i'll have "LINQ to Entities does not recognize the method"......"method cannot be translated into a store expression"
Wahid Bitar
And what about Lazy loading for `ProductList` ??
Wahid Bitar
@Wahid, lazy loading is unnecessary and inefficient for this problem. The answer I gave works as-is, with or without lazy loading turned on.
Craig Stuntz
I meant what if i want to make my POCO class support `LazyList<Product>` instead of `List<Product>` then i need to use `LazyList(IQueryable<Product>)` constructor inside the EF linq statement which of-course not supported. :(
Wahid Bitar
@Wahid: Then you have a different question than the one Scott asked. There is no `LazyList<T>` type in the framework, so when you ask your question you might want to be precise about what you are doing.
Craig Stuntz