Entity framework 查找实体框架上下文

Entity framework 查找实体框架上下文,entity-framework,entity-framework-4,Entity Framework,Entity Framework 4,通过我在这里和其他论坛上提出的各种问题,我得出的结论是,当涉及到实体框架中生成的实体上下文对象时,我不知道我在做什么 作为背景,我有大量使用LLBLGen Pro的经验,实体框架对我来说大约有三周的历史 假设我有一个名为“myContext”的上下文。在我的模型中有一个名为Employee的表/实体,因此我现在有一个myContext.Employees。我假设这意味着该属性表示我上下文中的员工实体集。但是,我的假设是错误的,因为我可以向上下文添加一个新实体,其中包含: myContext.Em

通过我在这里和其他论坛上提出的各种问题,我得出的结论是,当涉及到实体框架中生成的实体上下文对象时,我不知道我在做什么

作为背景,我有大量使用LLBLGen Pro的经验,实体框架对我来说大约有三周的历史

假设我有一个名为“myContext”的上下文。在我的模型中有一个名为Employee的表/实体,因此我现在有一个myContext.Employees。我假设这意味着该属性表示我上下文中的员工实体集。但是,我的假设是错误的,因为我可以向上下文添加一个新实体,其中包含:

myContext.Employees.AddObject(new Employee());
myContext.Projects.AddObject(new Project());
而这个新员工实体在myContext.Employees中没有出现。据我所知,找到这个新添加的实体的唯一方法是在myContext.ObjectStateManager中找到它。这听起来像myContext.Employees集,实际上不是上下文中的雇员实体集,而是数据库中存在的雇员实体的某种表示形式

为了进一步加深这种混淆,让我们假设我正在查看一个员工实体。存在一个与员工具有M:1关系的项目实体(员工可以有多个项目)。如果我想向特定员工添加新项目,我只需执行以下操作:

myEmployee.Projects.Add(new Project());
很好,正如我所期望的那样,这实际上将项目添加到了集合中。但这与上下文的ObjectSet属性的工作方式正好相反。如果我在上下文中添加了一个新项目:

myContext.Employees.AddObject(new Employee());
myContext.Projects.AddObject(new Project());
这不会改变项目集


如果有人能给我解释一下,我将不胜感激。另外,我真的需要上下文中所有员工(或项目)的集合,并且我希望它作为上下文的属性可用。EF是否可以实现这一点?

对象集是一个查询。就像LINQ的一切一样,它是懒惰的。在您枚举它或调用类似于
.Count()
的方法之前,它不会执行任何操作,此时将运行数据库查询,并将所有返回的实体与上下文中已有的实体合并

因此,您可以执行以下操作:

var activeEmployees = Context.Employees.Where(e => e.IsActive)
…而不运行查询

您可以进一步编写以下内容:

var orderedEmployees = activeEmployees.OrderBy(e => e.Name);
…同样,不运行查询

但如果你仔细观察场景:

var first = orderedEmployees.First();
…然后运行数据库查询。这是所有LINQ的共同点

如果要枚举上下文中已有的实体,则需要查看
ObjectStateManager
。因此,对于员工,您可以:

var states=EntityState.Added | | | EntityState.Deleted |///您需要什么
var emps=Context.ObjectStateManager.GetObjectStateEntries(状态)
.选择(e=>e.Entity)
.of type();

请注意,尽管这是可行的,但我不建议使用这种方式。通常,您不希望ObjectContext长期存在。出于这个原因和其他原因,它们并不真正适合作为对象的通用容器。使用常用的列表类型。将ObjectContext视为工作单元更为准确。通常,在一个工作单元中,您已经知道正在使用哪些实例。

这是我开始了解的想法。上下文中的那些属性(比如.Employees)不是用于状态管理的,而是用于数据库查询的。它们存在的事实使上下文看起来不像一个工作单元,而是某种数据容器。那么,在应用程序中,您是否建议创建和使用我自己的数据容器?例如,在ObservableCollection中,我自己进行更改跟踪?让
ObjectContext
进行更改跟踪。但是,如果您需要一份在职员工列表,并且不想每次都查询数据库,请务必使用
列表
或类似工具。只要意识到,如果列表超出了上下文,那么在更新中使用该实体之前,必须先分离和附加,因此通常只需再次查询就可以更容易(而且速度足够快)。缓存策略很难正确。正确,因此列表需要与ObjectContext同步。因此,从列表中添加/删除将导致添加/删除ObjectContext,反之亦然。伙计,这是一个痛苦的电线…希望微软有这样的内置。再次,如果你真的这样做,你有更大的问题。重新考虑ObjectContext,这样您就不会在显示和更新时使用相同的上下文。同样,将其视为一个工作单元。使用MVC或MVVM模式。在用户浏览屏幕时建立编辑模型,然后在单个更新操作中提交所有内容。上下文只会持续更新的时间,因为这是您的工作单元。其他工作单元正在填充每个屏幕。