【问题标题】:Entity Framework 6 Include missing实体框架 6 包括缺失
【发布时间】:2022-07-12 23:50:14
【问题描述】:

我有一个项目使用 Entity Framework 6 为 MVC 项目分成不同的类。一个类有一个通用接口,然后它被继承

public interface IRepository<T> where T : class
{
    IEnumerable<T> GetAll();
}

继承如下

public class Repository<T> : IRepository<T> where T : class
{
    protected readonly DbContext _context = null;
    private readonly DbSet<T> _entities;

    public GenericRepository(DbContext context)
    {
        _context = context;
        _entities = _context.Set<T>();
    }

    public IEnumerable<T> GetAll()
    {
        return _entities;
    }
}

这很好用,然后我在下面的客户类中使用它

public class CustomerRepository : Repository<Customer>, ICustomerRepository
{
    public CustomerRepository(DataContext context) : base(context)
    {
    }

    public List<Customer> GetPremiumCustomers()
    {
        return GetAll().Where(p => p.Premium).ToList();
    }
}

到目前为止一切顺利,一切都按预期返回。

我需要包括几个链接到客户的附加表。

当我转到Repository 类并针对_entities 时,我按 键我在菜单中看到Include

然后我进入CustomerRepository 并使用GetAll(). 和沿着该行的其他方法执行相同操作,但未显示Include

我尝试将 System.Data.Entity 添加到 Customer 类的顶部,但这也没有带来选项,但它在最顶级的类中可用?我在这里错过了什么?

我试图实现一些类似的东西

GetAll().Include("Address").Where(p => p.Premium).ToList()

【问题讨论】:

  • DbContext 类型是 UoW 模式的实现,DbSet&lt;T&gt; 类型是存储库模式的实现。为什么要在您自己的相同模式的实现中重新包装这些类型?你没有添加任何有价值的东西,只是更多的代码和糟糕的抽象,导致代码更难阅读、调试和使用。许多开发人员认为这样做是一种反模式。
  • 在不相关的笔记上。如果您尚未在此特定项目中实现 EF6,我敦促您考虑使用 EF Core (v3),因为这将使未来在 .net 核心项目中重用代码以及将您的项目移植到 .net 核心的工作更容易。需求不断出现。 EF Core 也在积极开发中,EF6 不再获得任何新功能(仅修复分类)。
  • @Igor 嗯,我遵循了 Mosh Hamedani 的付费教程。之所以选择EF6,主要是因为现阶段底层系统不兼容现代版EF
  • EF Core v3 与 .net 框架 4.7.2(及更高版本)/.net 标准 2.0/和 .net 核心兼容。除非您使用的是非常过时的 .net 框架版本,否则您应该没问题?
  • 好的,我可以通过 PMC 卸载它并尝试一下,但我可能必须检查文档以确保底层系统与之兼容....现在我想原来的问题仍然存在。

标签: c# asp.net-mvc entity-framework entity-framework-6


【解决方案1】:

在 Entity Framework 6 中,Include 方法在 DbQuery&lt;T&gt; 类上定义(DbSet&lt;T&gt; 派生自 DbQuery&lt;T&gt;)。另一方面,您的GetAll 方法返回IEnumerable&lt;T&gt;。编译器不知道您以IEnumerable&lt;T&gt; 的形式返回DbSet&lt;T&gt;,因此不提供该方法。

如果你想让GetAll的调用者使用Include方法,你可以改变返回类型,例如:

public interface IRepository<T> where T : class
{
    DbQuery<T> GetAll();
}

请注意,通过使用DbQuery&lt;T&gt; 作为您的返回类型,界面显示您正在使用实体框架,并且您不会向界面的用户隐藏此详细信息。为了隐藏这一点,您可以提供另一种方法,该方法接受包含参数并仍返回IEnumerable&lt;T&gt;

public interface IRepository<T> where T : class
{
    IEnumerable<T> GetAll();
    IEnumerable<T> GetAllWithInclude(string include);
}

public class Repository<T> : IRepository<T> where T : class
{
    protected readonly DbContext _context = null;
    private readonly DbSet<T> _entities;

    public GenericRepository(DbContext context)
    {
        _context = context;
        _entities = _context.Set<T>();
    }

    public IEnumerable<T> GetAll()
    {
        return _entities;
    }

    public IEnumerable<T> GetAllWithInclude(string include)
    {
        return _entities.Include(include);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-21
    • 1970-01-01
    • 2017-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多