【问题标题】:Entity Framework Generic Base Class实体框架通用基类
【发布时间】:2017-04-25 01:55:58
【问题描述】:

在创建数据优先的实体框架实现方面我别无选择。我想扩展生成的类以包含一个可以调用所有基本函数的通用基类。 (我知道如何更新 t4 模板)

更新(如果当前不在数据库中,则添加)、GetAll、选择(基于参数)和删除功能。我发现了一些我认为可能有用的东西,但它们没有完全限定的命名空间,我无法弄清楚信息的存储位置。

Creating base class for Entities in Entity Framework - 基本上是我的问题的重复,但答案不完整。

这个带有完全限定命名空间的基类的例子是什么?

【问题讨论】:

  • 仅仅因为您要针对现有数据库并不意味着您不能使用 Code First。这样可以避免更改模板。

标签: c# entity-framework generics


【解决方案1】:

即使您有数据库,您仍然可以使用 Code First。您可以生成模型。取决于您需要什么,请查看解决问题的 2 种不同方法。

通用存储库

public abstract class BaseRepository<TEntity> where TEntity : class
{
    protected DbContext context;

    protected BaseRepository(MyDbContext context) 
    {
        this.context = context;
    }

    public List<TEntity> GetAll()
    {
        // Set<TEntity> provides you an access to entity DbSet
        // Just like if you call context.Users or context.[AnyTableName]
        return context.Set<TEntity>().ToList();
    }
}

接下来您要实现特定于实体的存储库:

public class UserRepository : BaseRepository<User>
{
    public UserRepository(MyDbContext context) : base(context)
    {
    }
}

简单使用示例:

using (var context = new MyDbContext())
{
    var userRepository = new UserRepository(context);
    var users = userRepository.GetAll();
}

只需将您的泛型方法放在上下文中

public class MyContext : DbContext
{
    public DbSet<User> Users { get; set; }
    // ... more DbSets

    public List<TEntity> GetAll<TEntity>() where TEntity : class
    {
        return Set<TEntity>().ToList();
    }

    // For entities that implement INamedEntity interface
    // with property Name.
    public TNamedEntity FindByName<TNamedEntity>(string name)
        where TNamedEntity : INamedEntity, class
    {
        return Set<TNamedEntity>()
            .FirstOrDefault(entity => entity.Name == name);
    }
}

我使用 nuget 包 EntityFrameworkDbContextDbSet 来自 System.Data.Entity 命名空间。

希望这足以让您开始并实现您需要的所有方法。

【讨论】:

  • 感谢您花时间这么快回答。我一直在读到您不应该将存储库模式与实体框架一起使用,因为它基本上已经内置了。为什么双重工作?我还有200多张桌子。我要为每个表生成一个存储库吗?我有大约 120 个具有基本结构的表,我希望使用接口在我的 WebApi 中进行通用编辑,这就是我希望使用基类的原因。
  • 这是一个很好的观点。你应该在你的问题中提到这一切。让我为你重新写一下。
  • 谢谢!您是否愿意提供 using 语句或完全限定的命名空间?
  • 这太好了,谢谢。一个小问题,可能是我对泛型缺乏了解。我收到错误消息:类型“TEntity”必须是引用类型才能将其用作泛型类型或方法“DbContext.Set()”中的参数“TEntity”
  • @CherylTyme 我忘记了class 约束。是从我的脑海中写出来的,对不起:)。请查看更新。
猜你喜欢
  • 1970-01-01
  • 2011-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多