将EntityFramework 4实体公开为IList而不是IObjectSet

时间:2011-01-04 18:57:57

标签: c# entity-framework-4 iqueryable

我的Entity Framework 4项目中有一个'客户'POCO实体。我想将我的Customer实体暴露给我的上层作为通用列表而不是ObjectSet。

我有一个IUnitOfWork接口,如下所示:

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

在我的Entity Framework DAL(实现上述接口)中,我有以下内容:

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>() ;
       }            
    }
}

但是'CreateObjectSet(“Customers”)'行不起作用。每当我尝试添加新的“客户”时,都不会发生任何事情。有趣的是,如果我恢复使用IObjectSet,那么代码可以工作。例如:

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也有效,但我无法让IList工作,我不知道为什么。任何想法?

对原始问题的更正。使用IQueryable不起作用,IEnumerable也不起作用。这是因为Customer存储库需要提供“添加”和“删除”方法来添加/删除实体集合(在上面的示例中添加或删除客户实体)。 IQueryable或IEnumerable都不允许您添加或删除对象;相反,必须使用ICollection或IList。这让我回到原来的问题。我不想将我的集合作为ObjectSet公开给存储库。我想使用一个与EntityFramework无关的类型,即 - 我想使用通用列表。

有没有人有任何建议?我怀疑这是一种直截了当的方式,但我对框架不够熟悉,无法解决这个问题。

2 个答案:

答案 0 :(得分:2)

您似乎在所有这些中都缺少了一个存储库。存储库通常用于处理从ObjectSet<T>IList<T>(或大多数情况下为IEnumerable<T>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.
}

我通常会让我的UnitOfWork创建应该在工作单元中登记的存储库,以便通过存储库完成的任何操作都捆绑在一个操作中。

请记住,我的UnitOfWork只有两种方法。一个用于获取存储库,另一个用于提交工作单元。所有数据检索都由存储库处理。

答案 1 :(得分:1)

_customers.ToList()是罪魁祸首。 ToList执行查询并将该查询中的所有项复制到新的集合对象中。这个新的集合对象不提供ObjectSet具有的跟踪功能。