实体框架的奇怪约束异常

时间:2009-12-26 05:52:37

标签: c# entity-framework entity-relationship

我是实体框架的新手。 一周前,我遇到了currentcontext的常见问题,如果以非独特的方式使用它会引发异常,但这是固定的。

今天我遇到了一个新问题,一个非常新的问题,因为我甚至不知道为什么会这样,因为我认为我有相同的代码。

以下是我收到的错误:

Entities in 'Entities.WSUser_Detail' participate in 
the 'FK_WSUser_Detail_WSCountry' relationship. 
0 related 'WSCountry' were found. 1 'WSCountry' is expected.

这个错误的奇怪之处在于,在我的代码中,我从不引用任何WSUser_Detail对象。 有没有人提出过这种错误? 我的代码非常简单:

newUser = (from user in GB.Context.WSUsers
                where user.IDUser == nFound
                select user).FirstOrDefault();

newUser.DoNotSend = false;
newUser.IP = Request.UserHostAddress;
newUser.LastDtActivity = DateTime.Now;
newUser.Language1 = GB.User.Language;
newUser.LastVersion = sVersion;
newUser.FlushNextTime = false;

GB.Context.SaveChanges();

SaveChanges()

发生错误

我的代码中绝对没有调用WSUser_Detail ...所以我想知道他为什么要求一个永远不会调用的对象上的引用(但存在于实体上下文中)。

有什么想法吗?

奇怪的是,即使代码似乎没有改变,我也没有遇到过这个问题。

我更新了Model.edmx,以确保它不是原因,但它仍然不起作用,我已经多次检查过,因为我没有任何WSUser_Detail对象,所以错误不应该全部到来。< / p>

4 个答案:

答案 0 :(得分:1)

在数据库级别,我猜你在一个不允许为NULL的字段上有一个外键约束。你得到的模型在WSCountry和WSUser表之间有一个关系。

看起来你可能正试图保存一个无效的实体 - 一个不满足你的约束的实体。

我的猜测是你的WSUser需要有一个WSCountry实体集。是否有要设置的WSUser.WSCountry属性?

如果我的预感是正确的 - 请确保在保存前设置此项。

顺便说一下 - 'FK_WSUser_Detail_WSCountry'不建议对象 - 它指的是在数据库中设置的关系/ FK约束。实体框架使用这些约束来猜测您的实体应该如何相关..

答案 1 :(得分:1)

使用这个检查sys系统目录视图的小SQL脚本,你应该能够找出这个问题涉及哪两个表(及其列)之间的数据库约束 - 检查出来,大多数可能,这是必需的参考,例如你不能把它留空(你现在可能在你的代码中)。

SELECT
    fk.name ,
    t1.Name 'Parent table',
    c1.Name 'Parent column',
CASE WHEN c1.is_nullable = 0 THEN 'No' ELSE 'Yes'
END AS 'Parent column nullable',
    t2.Name 'Referenced table',
    c2.Name 'Referenced column'
FROM 
    sys.foreign_keys fk
INNER JOIN 
    sys.foreign_key_columns fkc ON fk.object_id = fkc.constraint_object_id
INNER JOIN 
    sys.tables t1 ON fkc.parent_object_id = t1.object_id    
INNER JOIN 
    sys.tables t2 ON fkc.referenced_object_id = t2.object_id
INNER JOIN 
    sys.columns c1 ON t1.object_id = c1.object_id AND fkc.parent_column_id = c1.column_id
INNER JOIN 
    sys.columns c2 ON t2.object_id = c2.object_id AND fkc.referenced_column_id = c2.column_id
WHERE 
    fk.name = 'FK_WSUser_Detail_WSCountry'

这应该为您提供父表和列以及引用的表和列 - 例如涉及你的外键关系的双方。

这应该有希望清除你所缺少的那块拼图。

答案 2 :(得分:0)

你的模型(EDMX)说WSUser和WSUser_Detail之间存在1:1的关系,但你的问题意味着你希望关系是1:0..1,所以你自己的理解或你的模型是不正确的。如果模型的关系基数为1:1,那么只要您创建或保存WSUser实体,实体框架就会检查它。这是您看到的错误的来源。

因为你的问题暗示这是这种关系的错误基数,你可能想要修复EDMX。为此,请在模型浏览器中找到FK_WSUser_Detail_WSCountry关联。单击它,然后在“属性”窗口中展开两个“结束”属性。更改相应结束的多重性。

答案 3 :(得分:0)

我最终发现了问题所在!

我正在使用全局上下文,如此处所示。 但是在之前的一些测试中,我添加了一个用户详细信息,其中不包含任何所需的wscountry引用。 所以它首先遇到了异常,这是我所期待的。

真正的问题是,只要使用方法AddTo(entityObj)添加了无效的实体对象,对SaveChanges()的任何进一步调用都会尝试将该对象添加到上下文中,即使导致问题的页面没有因为Context对象被“损坏”,所以已经存在了。

因此,在任何带有无效实体对象的AddTo之后,每次对SaveChanges()的调用都会被异常拒绝...

我的问题是:在尝试将其添加到使用的上下文中之前,是否有可能获得实体有效性等信息? 因为这样的致命错误是合乎逻辑的,但很难理解,因为它显示了几个小时前(使用全局上下文处理ASP.Net项目时)的错误。