考虑以下情况:
public abstract class Entity
{
public object Id { get; set; }
}
public abstract class Entity<T> : Entity
{
public new T Id { get; set; }
}
public class Foo : Entity<Guid>
{
}
如果我有以下代码:
var foo = new Foo { Id = Guid.NewGuid() };
db.Foos.Add(foo);
db.SaveChanges();
我收到DbEntityValidation
个异常,说Id
不允许为空。如果我调试,我可以看到Foo.Id
确实有一个值,但如果我进入基础对象到Entity
的水平,Id
在那里是空的,似乎这就是实体框架用于验证而不是非阴影属性的内容。我觉得我在这里遗漏了一些非常基本的东西;也许我今天早上还没有喝足够的咖啡。任何想法可能是什么问题?
答案 0 :(得分:1)
问题在于
public new T Id { get; set; }
...在Entity<T>
中隐藏了Entity中的Id属性。如果你这样做:
var foo = new Foo { Id = Guid.NewGuid() };
Entity entity = foo as Entity;
Console.WriteLine(entity.Id);
...那不会返回一个Guid,它将返回Entity.Id背后的内容,这是一个尚未设置的对象。
修改强>
克里斯想出了这个,这应该可以正常工作。public abstract class Entity<T> : Entity
{
public new T Id
{
get { return (T)base.Id; }
set { base.Id = value; }
}
}
答案 1 :(得分:1)
是的,我错过了一些简单的事情:实体框架不称职,不支持属性阴影。我认为这样做是因为在过去我成功地使用了阴影来改变属性属性(例如,只在子类中使该属性成为必需),但我从来没有真正尝试改变类型。
<强>更新强>
我想到,如果我只使用正确的值设置基本属性,一切都会好的。所以,我将Entity<T>
课改为以下内容:
public abstract class Entity<T> : Entity
{
public new T Id
{
get { return (T)base.Id; }
set { base.Id = value; }
}
}
异常消失,对象已成功保存到数据库中。这样做是否有任何不可预见的后果,我错过了?