【发布时间】:2011-08-15 22:06:46
【问题描述】:
当我尝试在 EF4 中保存具有父/子关系的实体时遇到问题。有时,孩子会被插入到父母之前——从参照约束的角度来看,这显然会导致问题。这两个表的结构如下:
OrderHeader
- OrderID (PK)
OrderDetails
- OrderID (PK)
- DetailID (PK)
(还有更多的列,但它们并不重要)。
注意:我们不会在 OrderDetails.OrderID 上公开真正的外键,而是使用触发器来强制 Details 表的 OrderID 存在于 Header 表中。公开 FK 可能是一种快速的解决方案,但在我们的应用程序中,不允许对数据库进行此类更改 - 我们必须处理遗留代码等。
查看设计器生成的 .edmx 文件中的 XML,我注意到它在概念模型(CSDL 部分)中创建了一个关联集和关联 - 并且关联是使用引用约束设置的。但是,它不会在 SSDL 部分中创建 AssociateSet 或 Assocation。似乎只有当 FK 在数据库中公开时才会添加这些。对于我测试过的其他数据库(如 AdventureWorks 或 Northwind),在数据库中确实有真正的 FK,当我从数据库生成模型时,我看到 EDMX 在 SSDL 中包含 Association 和 AssociationSet 部分。
EF 似乎忽略了我们在模型 (CSDL) 中的关联,而只是按表名的字母顺序插入 - 所以在这种情况下我们运气不好,因为 OrderDetail 在 OrderHeader 之前排序(我们当然不会在我们的例子中有权重命名表)。如果我在 SSDL 部分手动添加相应的 AssociationSet 和 Association,则保存以正确的顺序发生(首先插入 Header,然后插入 Detail)。但是,无论何时我们执行“从数据库更新模型”,这些手动更改都会消失,因此这不是一个非常实用的解决方案。我曾考虑尝试在运行时动态地进行修复,但感觉要解决一些应该“正常工作”的事情需要付出很多努力。
我希望 EF 在订购插入时能够尊重 CSDL 中定义的引用约束和/或关联。
【问题讨论】:
-
你们有一些可重复的样品吗?我这样做了几次,它很简单(在 EFv4 中)。
-
它在没有 FK 的情况下工作?对我来说,它每次都打破。一位同事已在 EF 论坛上发布了完整的详细信息。您可以在这里看到一个可重现的案例:social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/… 最重要的事情似乎是 SSDL 部分中没有 Assocation 和 AssociationSet。当它适合您时,SSDL 部分是否有关联?
-
当然......如果您没有特殊的触发器或没有分析 SQL,很容易错过“不正确”的行为。如果没有 FK,SQL Server 可能会让您在 Header 之前插入 Detail,但这是错误的行为。
-
您的描述看起来很常见 FK association 在 SSDL 中没有对应的部分。我会在家里检查。
-
顺便说一句。你在使用 EFv4 (.NET 4.0) 吗?您可能必须这样做,因为 .NET 3.5 中不存在引用约束。
标签: .net sql-server entity-framework .net-4.0 entity-framework-4