EntityFramework CTP5 DbContext T4 模板中的“virtual”关键字

22
CTP5自带的DbContext T4模板没有关联修正,也没有将所有属性标记为虚拟。这是否意味着当与上下文断开连接时不支持ChangeTracking?首先,即使通过动态代理跟踪,它是否支持在上下文跟踪时进行ChangeTracking?我看到更改跟踪的要求是所有属性都应标记为虚拟。
与EF4 POCO生成器相比,使用DbContext生成器是否会损失任何功能?
非常感谢您的回复。

这个问题部分地涉及到这里的内容:https://dev59.com/Om435IYBdhLWcg3wkA9e - gregmac
3
我的看法是,DbContext API(Code First t4模板使用)只是ObjectContext(POCO t4模板使用)的一个封装。因此,您可能不会失去任何功能,但在目前的时间点下(如果您在时间约束下工作),我建议使用ObjectContext,因为您会更快获得帮助,并且它有非常好的文档支持。我曾认为两个t4模板都将生成动态代理所需的属性标记为virtual,现在知道这并非总是如此。 - DotNetInfo
1
嗨,不知道你还在不在,但我认为你应该尝试使用EF 4.1。动态代理会自动生成在DbContext生成的POCO类周围。例如,不再需要虚拟关键字实现更改跟踪。如果需要ObjectContext,可以通过DbContext(进行一些强制转换操作后)访问它,因此您不会失去任何功能。 - Martín Coll
3个回答

1

这一切都关乎急切加载和惰性加载。看一下这个:

http://blogs.msdn.com/b/adonet/archive/2011/01/31/using-dbcontext-in-ef-feature-ctp5-part-6-loading-related-entities.aspx

    public class Person
    {
        public int Id { get; set; }
        public virtual Address Address { get; set; }
        // ...
    }

    public class Address
    {
        public int Id { get; set; }
        public string AddressLine1 { get; set; }
        // ...
    }

    static void Main(string[] args)
    {
        MyDatabaseContext db = new MyDatabaseContext();
        Person person = db.Persons.Where(x => x.Id == 1).First();
        // person.Address is loaded if the propertie Address, class Person 
        // is marked as virtual. If NOT its null.
    }

1

我认为使用DbContext生成器生成的类只会使用“延迟加载代理”,而不是“更改跟踪代理”(请注意,有两种类型的代理),如http://blogs.msdn.com/b/adonet/archive/2009/12/22/poco-proxies-part-1.aspx所述。正如你指出的那样,所有映射属性都必须是虚拟的才能使用更改跟踪代理。这对于仅使用延迟加载代理(其中只有导航属性必须是虚拟的)并非必需。

我认为Microsoft应该在T4模板中更改此设置,因为没有更改跟踪代理,速度会慢很多。特别是如果对象上下文中有很多实体。

我已经确认了这一点。在书籍《Programming Entity Framework: DbContext》的第66页中讨论了这个问题。您可以使用类似以下代码来验证对象是否使用更改跟踪代理。

Person p = context.People.Find(123);
bool b = p is IEntityWithChangeTracker;

我很惊讶T4模板默认不将所有属性设置为虚拟的。这似乎是一个奇怪的疏忽,除非他们有意为之。

0

被标记为虚拟的属性是另一个实体类型的属性。像 stringint 等属性从不被标记为虚拟。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接