Exposing EntityFramework 4 entities as IList instead of IObjectSet

依然范特西╮ 提交于 2019-12-11 07:08:45

问题


I have a 'Customer' POCO entity within my Entity Framework 4 project. I want to expose my Customer entities to my upper layers as a generic list rather than an ObjectSet.

I have an IUnitOfWork interface which looks as follows:

public interface IUnitOfWork
{
   string Save();
   IList<Customer> Customers { get; }
}

Down at my Entity Framework DAL (which implements the above interface) I have the following:

public class EntityContainer : ObjectContext, IUnitOfWork
{
    private IObjectSet<Customer> _customers;

    public IList<Customer> Customers 
    {
       get
       {
         if (_customers == null)
         {
             _customers = CreateObjectSet<Customer>("Customers");                    
         }
         return _customers.ToList<Customer>() ;
       }            
    }
}

However the 'CreateObjectSet("Customers")' line doesn't work. Every time I try to add a new 'Customer' nothing happens. Interestingly, if I revert to using an IObjectSet then the code works. For example:

public interface IUnitOfWork
{
    string Save();
    IObjectSet<Contact> Contacts { get; }
}


public class EntityContainer : ObjectContext, IUnitOfWork
{
    private IObjectSet<Customer> _customers;

    public IObjectSet<Customer> Customers 
    {
       get
       {
         if (_customers == null)
         {
             _customers = CreateObjectSet<Customer>("Customers");                    
         }
         return _customers;
       }            
    }
}

IQueryable also works, but I cannot get IList to work and I have no idea why. Anyone any ideas?

#

A correction to the original question. Using IQueryable doesn't work, nor does IEnumerable. This is because the Customer repository needs to provide 'Add' and 'Delete' methods to add/delete from the entity collection (add or remove customer entities in the above example). Neither IQueryable or IEnumerable allow you to add or remove objects; instead, an ICollection or IList must be used. This leaves me back at my original problem. I do not want to expose my collection to the repository as an ObjectSet. I want to use a type which is not tied to the EntityFramework i.e. - I want to use a generic list.

Has anyone any more suggestions? I suspect there's a straightforward way of doing this, but I'm not familiar enough with the framework to figure it out.


回答1:


_customers.ToList() is the culprit. ToList executes the query and copies all the items from that query into a new collection object. this new collection object does not provide the tracking capabilities that ObjectSet has.




回答2:


You seem to be missing a Repository in all of this. The Repository is usually what handles the conversion from ObjectSet<T> to IList<T> (or, in most cases, IEnumerable<T> or IQueryable<T>).

public class EntityContainer : ObjectContext
{
    private IObjectSet<Customer> _customers;

    public IObjectSet<Customer> Customers
    {
        get
        {
            return _customers ?? 
                ( _customers = CreateObjectSet<Customer>("Customers");
        }
    }
}

public class CustomerRepository
{
    EntityContext _context = new EntityContext();

    public IQueryable<Customer> FindAll()
    { 
        return _context.Customers;
    }

    public Customer FindById(int id)
    {
        return _context.Customers.Single(c => c.Id == id);
    }

    // And so on.
}

I usually then have my UnitOfWork create the Repositories that should be enlisted in the Unit of Work so that anything done through the repositories is bundled in a single operation.

Keep in mind, that my UnitOfWork only would have two methods. One for getting a repository and another for committing the Unit of Work. All data retrieval is handled by the Repositories.



来源:https://stackoverflow.com/questions/4597268/exposing-entityframework-4-entities-as-ilist-instead-of-iobjectset

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!