我们可以在不使用EF的情况下使用Generic Repository吗?这是一个好习惯吗?

时间:2014-11-03 07:07:17

标签: c# linq entity-framework repository-pattern dbml

我有一个应用程序,其中设计应用程序的人使用dbml来管理db类。但是我们有另一个我们经常需要连接的数据库,我们通常使用ado.net来连接它,因为我们不能使用相同的dbml。但是,我个人并不喜欢使用LINQ数据库,因为生成的自动代码会在我们添加新表或属性时导致错误。

我一直在尝试使用自我声明的类来实现存储库模式以映射到每个表,但是为了管理每个表上的操作,我们需要为每个实体单独存储库。我不确定我是否使用这种模式在正确的路径上,但如果我在这种情况下不使用EF,我们是否可以拥有一个通用存储库来表示一般操作或只是创建单独的存储库对于我们创建的每个实体?

此外,对于通用存储库,如果我能得到一些示例或指针,我将不胜感激。

很抱歉,如果我听起来多余的话。 提前谢谢!

1 个答案:

答案 0 :(得分:0)

如果您只使用CRUD操作(创建,读取,更新和删除),则通用存储库是个好主意 对我来说,我不喜欢通过DBML生成数据库实体,我通常手动编写实体及其映射,这里是我正在处理的项目的一些示例

首先是模型

public class Operator
{
    public virtual string OperatorName { get; set; }

    public virtual string LoginName { get; set; }

    public virtual string Email { get; set; }

    public virtual string PhoneNo { get; set; }

    public virtual short Status { get; set; }

    public virtual byte[] Password { get; set; }
}

更新: 要使存储库独立于提供程序,您应该定义存储库将使用的自定义上下文 首先定义接口

public interface IGenericContext
{
    void Add<T>(T entity)
        where T : class;

    void Update<T>(T entity)
        where T : class;

    void Delete<T>(T entity)
        where T : class;

    IQueryable<T> GetIQueryable<T>()
        where T : class;
}

这里是一个实现IGenericContext接口的EF上下文示例

public class EFContext : DbContext, IGenericContext
{
    public EFContext(string connectionName)
        : base(connectionName)
    {

    }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.AddFromAssembly(this.GetType().Assembly);
        base.OnModelCreating(modelBuilder);
    }

    public void Add<T>(T entity) where T : class
    {
        this.Set<T>().Add(entity);

        this.SaveChanges();
    }

    public void Update<T>(T entity) where T : class
    {
        this.Set<T>().Attach(entity);
        this.Entry(entity).State = EntityState.Modified;

        this.SaveChanges();
    }

    public void Delete<T>(T entity) where T : class
    {
        this.Set<T>().Attach(entity);
        this.Set<T>().Remove(entity);

        this.SaveChanges();
    }

    public IQueryable<T> GetIQueryable<T>() where T : class
    {
        return this.Set<T>();
    }
}

对于EF,您需要自己进行映射,如下所示

public class OperatorMapping : EntityTypeConfiguration<Operator>
{
    public OperatorMapping()
    {
        this.ToTable("Operators");
        this.Property(t => t.OperatorName).IsRequired().HasColumnName("OperatorName");
        this.HasKey(t => t.LoginName).Property(t => t.LoginName).HasColumnName("LoginName");
        this.Property(t => t.Email).IsRequired().HasColumnName("Email");
        this.Property(t => t.PhoneNo).HasColumnName("PhoneNo");
        this.Property(t => t.Status).IsRequired().HasColumnName("Status");
        this.Property(t => t.Password).IsRequired().HasColumnName("Password");
    }
}

然后是通用存储库,此存储库将使用IGenericContext而不是使用EF DBContext

public class Repository<TEntity>
    where TEntity : class, new()
{
    protected IGenericContext Context { get; set; }

    public Repository(IGenericContext context)
    {
        Context = context;
    }

    public void Add(TEntity entity)
    {
        Context.Add(entity);
    }

    public void Update(TEntity entity)
    {
        Context.Update(entity);
    }

    public void Delete(TEntity entity)
    {
        Context.Delete(entity);
    }

    public List<TEntity> ToList()
    {
        return Context.GetIQueryable<TEntity>().ToList();
    }
}

您需要做的就是创建DBContext,将其传递给通用存储库并执行操作

IGenericContext context = new EFContext("Infrastructure");
Repository<Operator> repository = new Repository<Operator>(context);
var operators = repository.ToList();

然后,您可以实现另一个执行基本CRUD操作的上下文,并且仍然可以使用相同的存储库