C# EF核心、DI、存储库模式和基本存储库结构的问题
我有.NETCoreRESTAPI,它包含混合结构,其中只包含存储库而不包含服务层 现在,我在基本存储库和主结构方面面临一个问题。让我先解释一下这个问题 所以,考虑一个实体。假设产品,下面是该实体的定义。此实体有一个名为FullAuditedEntity的基类C# EF核心、DI、存储库模式和基本存储库结构的问题,c#,dependency-injection,repository-pattern,asp.net-core-2.1,ef-core-2.1,C#,Dependency Injection,Repository Pattern,Asp.net Core 2.1,Ef Core 2.1,我有.NETCoreRESTAPI,它包含混合结构,其中只包含存储库而不包含服务层 现在,我在基本存储库和主结构方面面临一个问题。让我先解释一下这个问题 所以,考虑一个实体。假设产品,下面是该实体的定义。此实体有一个名为FullAuditedEntity的基类 [Table(name: "Products")] public class Product : FullAuditedEntity { public string Name { get; set; } } public cla
[Table(name: "Products")]
public class Product : FullAuditedEntity
{
public string Name { get; set; }
}
public class FullAuditedEntity: IFullAuditedEntity
{
public FullAuditedEntity() { }
[Key]
public virtual int Id { get; set; }
}
public interface IFullAuditedEntity
{
int Id { get; set; }
}
基本存储库及其接口如下所示
public class EntityBaseRepository<T> : IEntityBaseRepository<T> where T : class, IFullAuditedEntity, new()
{
private readonly ApplicationContext context;
public EntityBaseRepository(ApplicationContext context)
{
this.context = context;
}
public virtual IEnumerable<T> items => context.Set<T>().AsEnumerable().OrderByDescending(m => m.Id);
public virtual T GetSingle(int id) => context.Set<T>().FirstOrDefault(x => x.Id == id);
}
public interface IEntityBaseRepository<T> where T : class, new()
{
IEnumerable<T> items { get; }
T GetSingle(int id);
}
公共类EntityBaseRepository:EntityBaseRepository,其中T:class,IFullAuditedEntity,new()
{
私有只读应用程序上下文上下文;
公共EntityBaseRepository(ApplicationContext上下文)
{
this.context=上下文;
}
公共虚拟IEnumerable项=>context.Set().AsEnumerable().OrderByDescending(m=>m.Id);
公共虚拟T GetSingle(int-id)=>context.Set().FirstOrDefault(x=>x.id==id);
}
公共接口IEntityBaseRepository,其中T:class,new()
{
IEnumerable项{get;}
T GetSingle(int-id);
}
因此,我的产品存储库将是这样的
public interface IProductRepository : IEntityBaseRepository<Product> { }
public class ProductRepository : EntityBaseRepository<Product>, IProductRepository
{
private readonly ApplicationContext context;
public ProductRepository(ApplicationContext context) : base(context: context)
{
this.context = context;
}
}
公共接口IPProductRepository:IEntityBaseRepository{}
公共类ProductRepository:EntityBaseRepository、IPProductRepository
{
私有只读应用程序上下文上下文;
公共产品存储库(ApplicationContext上下文):基础(上下文:上下文)
{
this.context=上下文;
}
}
现在,到目前为止,一切都很好,我可以在控制器中访问这个存储库,并可以执行基类中列出的操作
我面临的问题:因此,在这个结构中,如果我试图添加任何没有FullAuditedEntity的新实体(请参阅上面的产品实体,我在那里有基类FullAuditedEntity),我的存储库结构将失败,并出现错误
假设我尝试添加新实体实现,而这个新实体有一个随机Id,因此我不想继承FullAuditedEntity基类。现在在这种情况下,大部分工作都会很好,但当我尝试为实现实体创建存储库时,它会给出一般性错误。请看下面的快照
到目前为止我所尝试的
我在考虑创建一个并行的基本存储库,它不作为泛型类继承FullAuditedEntity,但我不确定这是否是最佳实践。我还担心,如果我在当前的存储库模式和依赖项注入结构中犯了任何错误,该怎么办?
任何对世界的帮助都是最好的,真的很感激
提前感谢您的时间。存储库通常映射到数据库表。数据库表应该总是有一些列可以唯一地标识表中的行,通常将该列称为
Id
。因此,您正确地实现了FullAuditedEntity
,因为有Id
属性。但是,您的Id
的类型始终为int
。我建议您使用以下结构,然后您的Id
将是任何类型的结构,例如int
、decimal
、Guid
,等等:
/// <summary>
/// Abstraction of the Entity
/// </summary>
public interface IEntity
{
object Id { get; set; }
}
/// <summary>
/// Base class for IDs
/// </summary>
public abstract class Entity<T>: IEntity where T: struct
{
public T Id { get; set; }
object IEntity.Id
{
get { return Id; }
set {
Id = (T)value;
}
}
}
public class EntityBaseRepository<T> : IEntityBaseRepository<T> where T : class, IEntity, new()
{
// The code is omitted for the brevity
}
然后是您的实现
存储库:
public interface IImplementationRepository : IEntityBaseRepository<Implementation> { }
public class ImplementationRepository: BaseRepository<Implementation>
, IImplementationRepository
{
public override Implementation GetSingle(int id)
{
return base.GetSingle(id);
}
}
公共接口IIImplementationRepository:IEntityBaseRepository{}
公共类实现存储库:BaseRepository
,IImplementationRepository
{
公共重写实现GetSingle(int-id)
{
返回base.GetSingle(id);
}
}
更新1:
在我看来,最好使用使用使用ITRepository
的服务(Service layer
)。
因为它赋予你新的能力,例如:
我同意你对关键问题的看法。最终,实现类也会将Guid作为键,但我不想为我的某些实体继承这个FullAuditedEntity类,在这种情况下,这个结构对我不起作用,并给出了错误(请参阅相关错误的附加快照)。你能在那一点上指导我吗??您对这种无服务结构有何看法?@Bharat尽量避免使用没有Id的实体,因为很难找到如何更新此实体的方法。你能写一个不需要
Id
属性的实体的例子吗?@Bharat哦,太好了,我很高兴它对你有帮助!此外,您可以使用UnitOfWork模式改进代码存储库模式。然而,关于Repository模式和UnitOfWork模式有很多意见。@Bharat你能不能再提出一个问题来简化其他用户将来的搜索?每个帖子问一个问题是很好的做法。这是同样的问题,谢谢你的快速回复。。。
public interface IImplementationRepository : IEntityBaseRepository<Implementation> { }
public class ImplementationRepository: BaseRepository<Implementation>
, IImplementationRepository
{
public override Implementation GetSingle(int id)
{
return base.GetSingle(id);
}
}