为什么要将私有变量与属性一起使用 - 代码优先

时间:2015-08-21 14:06:36

标签: c# entity-framework variables properties

介绍

如果您将所有属性设置为虚拟,那么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;生成私有字段,所以?

1 个答案:

答案 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。您可以强制使用私有支持字段(映射支持字段)通过流畅的接口映射它并将其映射到内部类中。