- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
EF 5.0,在现有数据库工作流上使用代码优先。数据库有基本的 SalesOrder 和 SalesOrderLine 表,在 SalesOrderLine 上需要外键,如下所示;
public class SalesOrder
{
public SalesOrder()
{
this.SalesOrderLines = new List<SalesOrderLine>();
}
public int SalesOrderID { get; set; }
public int CustomerID { get; set; }
public virtual Customer Customer { get; set; }
public virtual ICollection<SalesOrderLine> SalesOrderLines { get; set; }
}
public class SalesOrderLine
{
public SalesOrderLine()
{
}
public int SalesOrderLineID { get; set; }
public int SalesOrderID { get; set; }
public virtual SalesOrder SalesOrder { get; set; }
}
public SalesOrderLineMap()
{
// Primary Key
this.HasKey(t => t.SalesOrderLineID);
// Table & Column Mappings
this.ToTable("SalesOrderLine");
this.Property(t => t.SalesOrderLineID).HasColumnName("SalesOrderLineID");
this.Property(t => t.SalesOrderID).HasColumnName("SalesOrderID");
// Relationships
this.HasRequired(t => t.SalesOrder)
.WithMany(t => t.SalesOrderLines)
.HasForeignKey(d => d.SalesOrderID);
}
现在根据这个页面: http://msdn.microsoft.com/en-us/data/jj713564
...我们被告知:
The following code removes a relationship by setting the foreign key to null. Note, that the foreign key property must be nullable.
course.DepartmentID = null;
Note: If the reference is in the added state (in this example, the course object), the reference navigation property will not be synchronized with the key values of a new object until SaveChanges is called. Synchronization does not occur because the object context does not contain permanent keys for added objects until they are saved. If you must have new objects fully synchronized as soon as you set the relationship, use one of the following methods.
By assigning a new object to a navigation property. The following code creates a relationship between a course and a department. If the objects are attached to the context, the course is also added to the department.Courses collection, and the corresponding foreign key property on the course object is set to the key property value of the department.
course.Department = department;
...我觉得不错!
现在我的问题:我有以下代码,但两个断言都失败了 - 为什么?
using (MyContext db = new MyContext ())
{
SalesOrder so = db.SalesOrders.First();
SalesOrderLine sol = db.SalesOrderLines.Create();
sol.SalesOrder = so;
Trace.Assert(sol.SalesOrderID == so.SalesOrderID);
Trace.Assert(so.SalesOrderLines.Contains(sol));
}
两个对象都附加到上下文 - 不是吗?我需要做一个 SaveChanges() 才能工作吗?如果是这样,这似乎有点愚蠢,而且当一个新对象被添加到外键集合时,我需要手动设置对象的所有引用,这很烦人。
-- 更新--
我应该将 Gert 的回答标记为正确,但我对此不是很满意,所以我会等一两天。 ...原因如下:
以下代码也不起作用:
SalesOrder so = db.SalesOrders.First();
SalesOrderLine sol = db.SalesOrderLines.Create();
db.SalesOrderLines.Add(sol);
sol.SalesOrder = so;
Trace.Assert(so.SalesOrderLines.Contains(sol));
唯一能工作的代码是这样的:
SalesOrder so = db.SalesOrders.First();
SalesOrderLine sol = db.SalesOrderLines.Create();
sol.SalesOrder = so;
db.SalesOrderLines.Add(sol);
Trace.Assert(so.SalesOrderLines.Contains(sol));
...换句话说,您必须先设置所有外键关系,然后调用 TYPE.Add(newObjectOfTYPE)在连接任何关系和外键字段之前。这意味着从完成 Create 到执行 Add(),对象基本上处于半生不熟的状态。我曾(错误地)认为自从我使用了 Create(),并且由于 Create() 返回了一个子类动态对象(而不是使用返回 POCO 对象的“new”),关系连接将被处理我。对我来说也很奇怪,您可以在使用 new 运算符创建的对象上调用 Add() 并且它会起作用,即使该对象不是子类类型...
换句话说,这会起作用:
SalesOrder so = db.SalesOrders.First();
SalesOrderLine sol = new SalesOrderLine();
sol.SalesOrder = so;
db.SalesOrderLines.Add(sol);
Trace.Assert(sol.SalesOrderID == so.SalesOrderID);
Trace.Assert(so.SalesOrderLines.Contains(sol));
...我的意思是,这很酷,但它让我想知道;使用“Create()”而不是 new 有什么意义,如果在任何一种情况下您都需要 Add() 对象(如果您希望它正确附加)?
最令我恼火的是以下失败;
SalesOrder so = db.SalesOrders.OrderBy(p => p.SalesOrderID).First();
SalesOrderLine sol = db.SalesOrderLines.Create();
sol.SalesOrder = so;
db.SalesOrderLines.Add(sol);
// NOTE: at this point in time, the SalesOrderId field has indeed been set to the SalesOrderId of the SalesOrder, and the Asserts will pass...
Trace.Assert(sol.SalesOrderID == so.SalesOrderID);
Trace.Assert(so.SalesOrderLines.Contains(sol));
sol.SalesOrder = db.SalesOrders.OrderBy(p => p.SalesOrderID).Skip(5).First();
// NOTE: at this point in time, the SalesOrderId field is ***STILL*** set to the SalesOrderId of the original SO, so the relationships are not being maintained!
// The Exception will be thrown!
if (so.SalesOrderID == sol.SalesOrderID)
throw new Exception("salesorderid not changed");
...这对我来说完全是废话,让我觉得 EntityFramework,即使是第 5 版,也像是宣纸桥上的雷区。为什么上面的代码无法在第二次分配 SalesOrder 属性时同步 SalesOrderId?我在这里缺少什么基本技巧?
最佳答案
我找到了我要找的东西! (并在此过程中学到了很多东西)
我认为 EF 在其动态代理中生成的是“更改跟踪代理”。这些代理类的行为更像是从 ADO.Net 实体数据模型派生的旧 EntityObject 部分类。
通过对动态生成的代理类进行一些反射(reflection)(感谢我在这篇文章中找到的信息:http://davedewinter.com/2010/04/08/viewing-generated-proxy-code-in-the-entity-framework/),我看到我的关系属性的“获取”被覆盖以进行延迟加载,但是“set”根本没有被覆盖,所以当然在 DetectChanges 被调用之前什么也没有发生,并且 DetectChanges 使用“与快照比较”方法检测变化。
进一步挖掘最终将我引向这对非常有用的帖子,我向所有使用 EF 的人推荐它们: http://blog.oneunicorn.com/2011/12/05/entity-types-supported-by-the-entity-framework/
http://blog.oneunicorn.com/2011/12/05/should-you-use-entity-framework-change-tracking-proxies/
不幸的是,为了让 EF 生成更改跟踪代理,必须发生以下情况(引用自上文):
The rules that your classes must follow to enable change-tracking proxies are quite strict and restrictive. This limits how you can define your entities and prevents the use of things like private properties or even private setters. The rules are: The class must be public and not sealed. All properties must have public/protected virtual getters and setters. Collection navigation properties must be declared as ICollection<T>. They cannot be IList<T>, List<T>, HashSet<T>, and so on.
Because the rules are so restrictive it’s easy to get something wrong and the result is you won’t get a change-tracking proxy. For example, missing a virtual, or making a setter internal.
...他继续提到有关更改跟踪代理的其他事情,以及为什么它们可能表现出更好或更差的性能。
在我看来,更改跟踪代理类会很好,因为我来自 ADO.Net 实体模型世界,而且我已经习惯了以这种方式工作,但我也有一些相当丰富的类,我不确定我是否能够满足所有标准。此外,第二个要点让我相当紧张(尽管我想我可以创建一个循环遍历我所有实体的单元测试,对每个实体执行 Create(0,然后测试 IEntityWithChangeTracker 接口(interface)的结果对象)。
在我原来的例子中,通过将我所有的属性设置为虚拟,我确实得到了 IEntityWithChangeTracker 类型的代理类,但我觉得有点......我不知道......“脏”......使用它们,所以我想我只需要接受它并记住在做作业时总是设置我的关系的双方。
无论如何,感谢您的帮助!
干杯,克里斯
关于entity-framework-5 - EF 5.0 新对象 : assign foreign key property does not set the foreign key id, 或添加到集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14183423/
出现在 python 2.7.8 中。 3.4.1 不会发生这种情况。 示例: >>> id(id) 140117478913736 >>> id(id) 140117478913736 >>> id
好吧,我对动态创建的控件的 ID 很困惑。 Public Class TestClass Inherits Panel Implements INamingContainer
我收到下面的错误,说有堆栈溢出。发生这种情况是因为带有 IN (id, id, id...id) 的 SQL 语句有大量参数。有没有什么办法解决这一问题?这是在我使用 Eclipse 的本地环境中发生
为什么 CPython(不知道其他 Python 实现)有以下行为? tuple1 = () tuple2 = ()
为什么 CPython(对其他 Python 实现一无所知)有以下行为? tuple1 = () tuple2 = ()
非常简单的问题:当我有一个持久对象时,它通常有一个名为 ID 的属性(对于抽象类)。 那么..命名约定是ID还是Id? 例如。 public int ID { get; set; } 或 public
知道为什么我会收到此错误,我已经尝试了所有命名约定(小写/大写) 我正在使用 Vaadin,这是我的代码片段: public class Usercontainer extends BeanI
为什么 CPython(不知道其他 Python 实现)有以下行为? tuple1 = () tuple2 = ()
我需要改变表的所有主键 UPDATE TODO SET id = id + 1 但我做不到(Demo 来自 Ahmad Al-Mutawa 的回答)描述了原因。主键不能这样改。 我也不能根据这是 sq
我正在尝试列出与用户相关的讨论列表。 想象一下,如果你愿意的话: posts -------------------------------------------------------------
我有一个表,其中包含一些具有自己的 ID 和共享 SKU key 的文章。我尝试使用左连接进行查询,并使用组结果获取从查询返回的所有 id。 我的数据结构是这样的: id - name -
在下表People中: id name 1 James 2 Yun 3 Ethan 如果我想找到最大 ID,我可以运行此查询 select max(id) id from People; 结果是
我正在产品页面上创建评论模块,其中显示垃圾评论选项,并显示 onclick 显示和隐藏弹出窗口。现在它在单个评论中工作正常但是当评论是两个时它同时打开两个因为类是相同的。现在这就是为什么我想要获取父
根据 REST 哲学,PUT操作应该(取自维基百科): PUT http://example.com/resources/142 Update the address member of the co
我想知道如何在使用 PHP 或 JavaScript 进行身份验证后从 Google Analytics 获取 Property Id、View Id 和 Account Id?因为我希望能够将它们存
我想使用所选按钮的 ID 进行删除。但我不知道如何从中获取/获取 id。我尝试了 this.id 但不起作用。 这是我创建按钮的地方: var deleteEmployer= document.cre
我有一个具有以下结构的表“表” ID LinkedWith 12 13 13 12 14 13 15 14 16
请不要在未阅读问题的情况下将问题标记为重复。我确实发布了一个类似的问题,但 STACKOVERFLOW 社区成员要求我单独重新发布修改后的问题,因为考虑到一个小而微妙的修改,解决方案要复杂得多。 假设
在 Android Studio 中,我创建了一个 Person.java 类。我使用Generate 创建了getter 和setter 以及构造函数。 这是我的 Person.java 类: pu
如何在 jQuery 中制作这样的东西: //这是显示的主体 ID //当我悬停 #hover-id 时,我希望 #principal-id 消失并更改 。但是当我将光标放在 #this-id 上时
我是一名优秀的程序员,十分优秀!