我有一个用于实体框架的抽象类。然后我继承了类并在需要时覆盖。在这种情况下,我有一个我想要删除的帖子,我想删除与帖子相关的评论。逻辑很简单,但我似乎得到了奇怪的类型问题。
这是我所期望的。但是,entity.ID
不存在。事实上,
实体对象根本没有属性(就visual studio intellisense而言)。我试图抛出它,它说它不能将Post转换为MyProject.Models.Post,即使它应该是完全相同的类。因此,似乎通过使用泛型类型并在继承期间将其强制转换,它正在创建一个同名的新类。
public abstract class MyAbstractService<T>
{
public virtual void Delete<T>(T entity)
{
this.context.Set<T>().Remove(entity);
}
}
public abstract class MyAbstractService :AbstractService<Post>
{
public override void Delete<Post>(Post entity)
{
this.context.PostComments.RemoveRange(this.context.PostComments.Where(x => x.Post.ID == entity.ID));
base.Delete(entity);
}
}
我能够通过使用下面的方法解决这个类型的问题,但我不明白为什么这发生在第一位。我假设有一个更好的方法来处理这个比我在这里使用的铸造方法。如果没有其他选择,那么首先会发生什么?
public override void Delete<Post>(Post entity)
{
MyProject.Models.Post pst = entity as MyProject.Models.Post;
this.context.PostComments.RemoveRange(this.context.PostComments.Where(x => x.Post.ID == pst.ID));
base.Delete(entity);
}
基于这些评论,似乎这样的东西将是实现删除的更优选方式,但是我仍然觉得抽象方法是有用的,因为我已经将它用于许多其他没有关系的实体。
public void Delete(Post entity)
{
this.context.PostComments.RemoveRange(this.context.PostComments.Where(x => x.Post.ID == entity.ID));
base.Delete(entity);
}
答案 0 :(得分:2)
Delete
上的MyAbstractService
方法正在定义一种方法,表明任何MyAbstractService
都可以删除任何类型的任何对象。
因此,当您从该抽象类继承并提供该方法的实现时,您需要提供一种能够删除任何类型的任何对象的方法。您已在实施中为您的通用类型Post
命名(您可以随意调用它),但调用该通用参数Post
并不代表实例属于Post
类型,它只是通用类型的名称,因此对象可以是任何类型的 。如果您希望将对象视为Post
类型的对象,则需要将其投射,就像您正在进行的那样。
现在你有了一个签名声明的方法它可以接受任何类型的对象,但实际上它只会失败,如果&# #39;不是Post
类型的对象。这个糟糕的设计;你的API对其来电者说谎。
相反,对于MyAbstractService
类型,有一个方法可以删除任何类型的对象,这是没有意义的。 Delete
开始时不应该是通用的。相反,它应该只使用类的通用类型,而不是定义第二个泛型类型(你也称之为T
,令人困惑)。