代码之家  ›  专栏  ›  技术社区  ›  JJ Yong

继承的通用存储库问题

  •  -1
  • JJ Yong  · 技术社区  · 7 年前

    T Record<T> . 然后我扩展了它们,添加了更多的数据访问设施和自定义 Save() Delete() 记录(<);T> 默认方法。

    以下是覆盖的 Delete 实体中的方法(我要调用的方法)

    public partial class Document : Record<Document>
    {
        public new int Delete()
        {
            int rowsAffected;
            using (var uow = DB.GetInstance().GetTransaction())
            {
                rowsAffected = base.Delete();
                LogSystem("Deleting", "Deleting a document", 0, 0, GUID);
                uow.Complete();
            }
            return rowsAffected;
        }
    }
    

    然后,当我创建通用存储库时,调用的方法来自基类 记录(<);T> 而不是我来自实体的自定义项。当我打电话给 entityRepository.Delete() 方法 应该调用实体中的方法,而不是默认值中的方法

    通用存储库类如下:

    public abstract class GenericRepository<T> : IGenericRepository<T> where T : Record<T>, new()
    {
        public void Delete(T entity)
        {
            entity.Delete();
        }
    }
    
    2 回复  |  直到 5 年前
        1
  •  0
  •   C. Sura    7 年前

    这个问题的原因是 GenericRepository 您将T指定为“从记录中派生的东西”。苏打电话来 entity.Delete() ,此调用将链接到此基本方法,因为对于T的所有可能实例,这只执行一次。

    如果您有权访问 Record<T> 同学们,只要 Delete() Document .

    如果没有,请尝试使用以下内容:

    public class ExtendedRecord<T>: Record<T>
    {
      public virtual new int Delete()
      {
        base.Delete();
      }
    }
    
    public partial class Document : ExtendedRecord<Document>
    {
      public override int Delete()
      {
        // ...
      }
    }
    
    public abstract class GenericRepository<T> : IGenericRepository<T>
      where T : ExtendedRecord<T>, new()
    {
      // ...
    }
    
        2
  •  0
  •   Community CDub    4 年前

    坦白:我不知道PetaPoco及其模板生成器。

    与PetaPoco IMHO相比,这个问题更多地与OO(特别是继承)相关。如果通用存储库是使用 Record<T> 这也是每个实体的基类,然后发生的事情正如预期的那样。您需要仔细研究类的继承。

    为了与ORM功能相匹配,您可能需要对我在下面提出的解决方案进行一些更改。

    解决方案1:

    声明一个新的基类或接口,如下所示:

    public interface IEntityBase{.....
    

    包括必要的成员,如 Delete 接口中的方法。

    然后,从该接口导出每个实体:

    public partial class Document : Record<Document>, IEntityBase
    

    然后,使用此接口创建一个通用存储库,而不是 某物 如下所示:

    public abstract class GenericRepository<T> : IGenericRepository<T> where T : IEntityBase
    

    这样,您就可以在不改变现有代码的情况下实现目标。

    解决方案2:

    另一个 肮脏的 解决方案是铸造 根据其实际情况。

    public void Delete(T entity)
    {
        if(typeof(T) == typeof(Document))
            Document myEntity = (Document)entity;
        myEntity.Delete();
    }
    

    每种铸造方法都绝对是个坏主意。在代码中寻找更好的集中位置。我只是想给你带路。

    解决方案3:

    其他想法是 删去 记录(<);T> virtual 方法但我不确定你的ORM是如何工作的,甚至不知道你的ORM是否允许这样做,所以我不会对此发表评论。