查找实体框架上下文 [英] Finding Entity Framework contexts

查看:96
本文介绍了查找实体框架上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



作为背景,我有很多使用LLBLGen Pro的经验,实体框架对我来说大约三个星期。



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

  myContext.Employees.AddObject(new Employee ());在myContext.Employees中,这个新的Employee实体显示无效

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



为了进一步增加这种混淆,让我说我正在看一个单一的员工实体。有一个与员工具有M:1关系的项目实体(员工可以有多个项目)。如果我想为特定的员工添加一个新的项目,我只需要:

  myEmployee.Projects.Add(new Project )); 

很棒,这实际上是按照我的预期将项目添加到集合中。但是,面对上下文中ObjectSet属性的工作方式,这一切正是如此。如果我添加一个新的项目到上下文:

  myContext.Projects.AddObject(new Project()); 

这不会改变项目集。



如果有人向我解释,我非常感激。此外,我真的希望在上下文中收集所有的Employees(或Projects),并且我希望它可以作为上下文的属性。这是可能的EF?

解决方案

一个 ObjectSet 是一个查询。像LINQ中的一切,它是懒惰的。直到你枚举它或者调用一个方法,如 .Count(),此时运行一个数据库查询,任何返回的实体与已经在



所以你可以这样做:

  var在线时间一个查询。



您可以进一步撰写:

  var orderedEmployees = activeEmployees.OrderBy(e => e.Name); 

...再次,不运行查询。



但是,如果您查看该集合:

  var first = orderedEmployees.First(); 

...然后运行一个DB查询。这对于所有的LINQ来说是很常见的。



如果你想枚举上下文中的实体,你需要看 ObjectStateManager ,而不是。对于员工,您可以执行以下操作:

  var states = EntityState.Added || EntityState.Deleted || //任何你需要
var emps = Context.ObjectStateManager.GetObjectStateEntries(states)
.Select(e => e.Entity)
.OfType< Employee>();

请注意,虽然这有效,但我不建议您的工作方式。通常情况下,您不希望ObjectContexts长期存在。由于这个原因和其他原因,它们并不真正适合作为通用的物体容器。使用通常的列表类型。将ObjectContext视为工作单位更为准确。通常,在一个工作单位中,您已经知道您正在使用哪些实例。


Through various questions I have asked here and other forums, I have come to the conclusion that I have no idea what I'm doing when it comes to the generated entity context objects in Entity Framework.

As background, I have a ton of experience using LLBLGen Pro, and Entity Framework is about three weeks old to me.

Lets say I have a context called "myContext". There is a table/entity called Employee in my model, so I now have a myContext.Employees. I assume this to mean that this property represents the set of Employee entities in my context. However, I assume wrong, as I can add a new entity to the context with:

myContext.Employees.AddObject(new Employee());

and this new Employee entity appears nowhere in myContext.Employees. From what I gather, the only way to find this newly added entity is to track it down hiding in the myContext.ObjectStateManager. This sounds to me like the myContext.Employees set is in fact not the set of Employee entities in the context, but rather some kind of representation of the Employee entities that exist in the database.

To add further to this confusion, Lets say I am looking at a single Employee entity. There is a Project entity that has a M:1 relationship with Employee (an employee can have multiple projects). If I want to add a new project to a particular employee, I just do:

myEmployee.Projects.Add(new Project());

Great, this actually adds the Project to the collection as I would expect. But this flies right in the face of how the ObjectSet properties off of the context work. If I add a new Project to the context with:

myContext.Projects.AddObject(new Project());

this does not alter the Projects set.

I would appreciate it very much if someone were to explain this to me. Also, I really want a collection of all the Employees (or Projects) in the context, and I want it available as a property of the context. Is this possible with EF?

解决方案

An ObjectSet is a query. Like everything in LINQ, it's lazy. It does nothing until you either enumerate it or call a method like .Count(), at which point a database query is run, and any returned entities are merged with those already in the context.

So you can do something like:

var activeEmployees = Context.Employees.Where(e => e.IsActive)

...without running a query.

You can further compose this:

var orderedEmployees = activeEmployees.OrderBy(e => e.Name);

...again, without running a query.

But if you look into the set:

var first = orderedEmployees.First();

...then a DB query is run. This is common to all LINQ.

If you want to enumerate entities already in the context, you need to look towards the ObjectStateManager, instead. So for Employees, you can do:

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

Note that although this works, it is not a way that I would recommend working. Typically, you do not want your ObjectContexts to be long-lived. For this, and other reasons, they are not really suitable to be a general-purpose container of objects. Use the usual List types for that. It is more accurate to think of an ObjectContext as a unit of work. Typically, in a unit of work you already know which instances you are working with.

这篇关于查找实体框架上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆