Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# EF核心、DI、存储库模式和基本存储库结构的问题_C#_Dependency Injection_Repository Pattern_Asp.net Core 2.1_Ef Core 2.1 - Fatal编程技术网

C# EF核心、DI、存储库模式和基本存储库结构的问题

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

我有.NETCoreRESTAPI,它包含混合结构,其中只包含存储库而不包含服务层

现在,我在基本存储库和主结构方面面临一个问题。让我先解释一下这个问题

所以,考虑一个实体。假设产品,下面是该实体的定义。此实体有一个名为FullAuditedEntity的基类

[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);
        }
    }