1

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

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

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

对不起,如果我听起来多余。提前致谢!

4

1 回答 1

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 操作的上下文,并且仍然可以使用相同的存储库

于 2014-11-03T07:45:30.110 回答