我有一个应用程序,其中设计应用程序的人使用dbml来管理数据库类。但我们有另一个数据库,我们经常需要连接到它,我们通常使用ado.net来连接它,因为我们不能使用相同的dbml。然而,我个人不喜欢使用LINQ数据库,因为每当我们添加新的表或属性时,生成的自动代码都会导致错误。
我一直在尝试实现一个具有自声明类的存储库模式,以映射到每个表,但为了管理每个表上的操作,我们需要为每个实体提供一个单独的存储库。我不确定我使用这种模式是否正确,但如果我在这种情况下没有使用EF,我们是否可以有一个通用的存储库来表示一般操作,或者只为我们创建的每个实体创建单独的存储库?
此外,对于通用存储库,如果我能得到一些示例或指向它的指针,我将不胜感激
如果我听起来多余,我很抱歉。提前感谢!
如果您只使用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操作的上下文,并且仍然可以使用相同的存储库