我在.Net中使用PetaPoco作为microORM的N层解决方案。我得到了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();
}
}
答案 0 :(得分:0)
忏悔:我不了解PetaPoco及其模板生成器。
与PetaPoco恕我直言相比,问题与OO(特别是继承)有关。如果使用Record<T>
创建通用存储库,public interface IEntityBase{.....
也是每个实体的基类,那么发生的事情就像预期的那样。您需要密切关注类的继承。
您可能需要对我在下面提出的解决方案进行一些更改,以便与ORM功能相匹配。
声明一个新的基类或接口,如下所示:
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();
}
转换为其实际实例。
Delete
在每种方法中进行投射绝对是个坏主意。在代码中寻找更好的集中位置。我只是想告诉你的方式。
其他想法是在Record<T>
virtual
方法中制作//Prepare the response
$numberOfPages = ceil( $numberOfRows / $rowsPerPage );
方法。但我不确定你的ORM是如何工作的,或者即使你的ORM允许这样做,所以我不会对此发表评论。
答案 1 :(得分:0)
此问题的原因在于,在GenericRepository
中,您将T指定为&#34;从Record&#34;中获取的内容。所以wenn调用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()
{
// ...
}