介绍
如果您将所有属性设置为虚拟,那么EF将在运行时生成源自您的POCO分类的代理类,这些代理允许EF实时查找有关更改而不必捕获对象的原始值,然后保存时扫描更改(这显然具有性能和内存使用优势,但除非您将大量实体加载到内存中,否则差异可以忽略不计)。这些被称为“更改跟踪代理”,如果您将导航属性设置为虚拟,那么仍会生成代理,但它更简单,并且只包含一些逻辑,以便在您访问导航属性时执行延迟加载。 / p>
参考:http://social.msdn.microsoft.com/Forums/en/adonetefx/thread/99d8d4a1-5ab1-42dc-b9db-5087be02162d
[1]
public virtual ICollection<Log> Logs { get; set; }
[2]
private ICollection<Log> _logs;
public virtual ICollection<Log> Logs
{
get
{
if(_logs == null) Logs = new HashSet<Log>();
return Logs ;
}
private set {}
}
[3]
private ICollection<Log> _logs;
public virtual ICollection<Log> Logs
{
get
{
if(_logs == null) _logs = new HashSet<Log>();
return _logs;
}
set {_logs = value; }
}
如何更好地思考EF - Code first?
为什么有些人会使用包含属性的私有字段?
私有设置可以帮助避免修改完整列表在[1]中,我们可以使用空引用,在使用属性
之前强制验证if是否为null但是,私有变量/字段,我不明白为什么是必要的。我认为&#34;后端&#34;生成私有字段,所以?
答案 0 :(得分:0)
就像你说的那样,在[1]中你可以有一个空的引用异常(通常在你创建一个新的父类然后添加一个新的日志时。)
避免它的方法是:
- 写[2]
- 在父类构造函数中初始化
- 使用c#5,你可以写
public virtual ICollection<Log> Logs { get; set; } = new new HashSet<Log>();
[3]没有用(如果初始化Logs属性,EF不需要访问setter)。
另一件有趣的事情是你可以使用你自己的收藏品,即
public class LogCollection : ObservableCollection<Log>
{
public Post Add(string content)
{
Log log = new Log
{
Date = DateTime.Now,
Content = content
};
Add(log);
return log;
}
}
然后在master类中使用它而不是ICollection,即
public virtual LogCollection Logs
{
get
{
if(_logs == null) Logs = new HashSet<Log>();
return Logs ;
};
private set;
}
通常我在类构造函数中初始化集合,我不使用支持字段,我的setter是公共的(但可能我从未在父类之外使用它,所以它是一种实现它的愚蠢方法)。但这是我使用c#4.x
的方式修改强> 关于你的问题的一部分,EF不使用支持字段,它只访问属性setter和getter。您可以强制使用私有支持字段(映射支持字段)通过流畅的接口映射它并将其映射到内部类中。