[英]Generic repository issue with inheritance
我在 .Net 中有 N 层解决方案,使用 PetaPoco 作为 microORM。 我得到了从 PetaPoco 的模板生成器生成的实体。 这些实体T
派生自基类Record<T>
。 然后我扩展它们,添加更多数据访问工具和自定义Save()
和Delete()
方法,它们覆盖Record<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;
}
}
然后,当我创建通用存储库时,调用的方法来自基类Record<T>
而不是来自实体的自定义方法。 当我调用entityRepository.Delete()
方法时,应调用实体中的Delete()
方法,而不是默认Record<T>
类中的方法。
通用存储库类如下:
public abstract class GenericRepository<T> : IGenericRepository<T> where T : Record<T>, new()
{
public void Delete(T entity)
{
entity.Delete();
}
}
忏悔:我对 PetaPoco 及其模板生成器一无所知。
与 PetaPoco 恕我直言相比,该问题与 OO(特别是继承)更相关。 如果使用Record<T>
创建通用存储库,它也是每个实体的基类,那么发生的事情正如预期的那样。 您需要仔细研究类的继承。
您可能需要对我在下面提出的解决方案进行一些更改以匹配 ORM 功能。
声明一个新的基类或接口,如下所示:
public interface IEntityBase{.....
在接口中包含必要的成员,如Delete
方法。
然后,也从这个接口派生每个实体:
public partial class Document : Record<Document>, IEntityBase
然后,创建这个接口,而不是一个通用的存储库Record<T>
类似下面:
public abstract class GenericRepository<T> : IGenericRepository<T> where T : IEntityBase
这样,您无需更改现有代码即可实现目标。
另一个肮脏的解决方案是将Record<T>
为它的实际实例。
public void Delete(T entity)
{
if(typeof(T) == typeof(Document))
Document myEntity = (Document)entity;
myEntity.Delete();
}
在每种方法中进行铸造绝对是个坏主意。 在您的代码中寻找一些更好的集中位置。 我只是想给你指路。
其他想法是使Record<T>
的Delete
方法成为virtual
方法。 但我不确定你的 ORM 是如何工作的,或者你的 ORM 是否允许这样做,所以我不会对此发表评论。
此问题的原因是在您的GenericRepository
您将 T 指定为“从 Record 派生的东西”。 因此,调用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()
{
// ...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.