查找实体框架上下文

Mik*_*tes 13 entity-framework entity-framework-4

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

作为背景,我有很多使用LLBLGen Pro的经验,实体框架对我来说大约有三周的时间.

假设我有一个名为"myContext"的上下文.在我的模型中有一个名为Employee的表/实体,所以我现在有一个myContext.Employees.我假设这意味着此属性表示我的上下文中的Employee实体集.但是,我假设错了,因为我可以在上下文中添加一个新实体:

myContext.Employees.AddObject(new Employee());
Run Code Online (Sandbox Code Playgroud)

而这个新的Employee实体在myContext.Employees 中无处可见.从我收集的内容来看,找到这个新添加的实体的唯一方法是在myContext.ObjectStateManager中隐藏它.这听起来像myContext.Employees集实际上不是上下文中的Employee实体集,而是数据库中存在的Employee实体的某种表示.

为了进一步加剧这种混乱,让我们说我正在看一个单一的Employee实体.有一个Project实体与Employee有一个M:1的关系(一个员工可以有多个项目).如果我想向特定员工添加新项目,我只需:

myEmployee.Projects.Add(new Project());
Run Code Online (Sandbox Code Playgroud)

太棒了,这实际上就像我期望的那样将项目添加到集合中.但是,面对上下文中ObjectSet属性的工作原理,这种情况仍然存在.如果我将新项目添加到上下文中:

myContext.Projects.AddObject(new Project());
Run Code Online (Sandbox Code Playgroud)

这不会改变项目集.

如果有人向我解释这一点,我将非常感激.另外,我真的想要上下文中所有Employees(或Projects)的集合,并且我希望它可用作上下文的属性.这可能与EF有关吗?

Cra*_*ntz 16

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

所以你可以这样做:

var activeEmployees = Context.Employees.Where(e => e.IsActive)
Run Code Online (Sandbox Code Playgroud)

...没有运行查询.

你可以进一步撰写:

var orderedEmployees = activeEmployees.OrderBy(e => e.Name);
Run Code Online (Sandbox Code Playgroud)

...再次,没有运行查询.

但是如果你看一下这套:

var first = orderedEmployees.First();
Run Code Online (Sandbox Code Playgroud)

...然后运行数据库查询.这对所有LINQ都是通用的.

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

var states = EntityState.Added || EntityState.Deleted || // whatever you need
var emps = Context.ObjectStateManager.GetObjectStateEntries(states)
                                     .Select(e => e.Entity)
                                     .OfType<Employee>();
Run Code Online (Sandbox Code Playgroud)

请注意,虽然这有效,但这不是我推荐的工作方式.通常,您不希望ObjectContexts具有长期使用寿命.由于这个原因和其他原因,它们并不适合作为对象的通用容器.使用通常的List类型.将ObjectContext视为一个工作单元更准确.通常,在一个工作单元中,您已经知道您正在使用哪些实例.

  • 使用MVC或MVVM模式.在用户浏览屏幕时构建编辑模型,然后在单个更新操作中提交所有内容.只有更新时,上下文才会持续,因为这是您的工作单元.其他工作单元填充每个屏幕. (4认同)