在ReferentialConstraint中,一个依赖属性被映射到一个由存储生成的列。

110

当我向数据库写入数据时,出现以下错误:

ReferentialConstraint中的一个依赖属性被映射到了一个由数据库自动生成的列上。列名:'PaymentId'。

public bool PayForItem(int terminalId, double paymentAmount, 
      eNums.MasterCategoryEnum  mastercategoryEnum, int CategoryId, int CategoryItemId)
    {

        using (var dbEntities = new DatabaseAccess.Schema.EntityModel())
        {
            int pinnumber = 0;
            long pinid = 1; //getPinId(terminalId,ref pinnumber) ;
            var payment = new DatabaseAccess.Schema.Payment();
            payment.CategoryId = CategoryId;
            payment.ItemCategoryId = CategoryItemId;
            payment.PaymentAmount = (decimal)paymentAmount;
            payment.TerminalId = terminalId;
            payment.PinId = pinid;

            payment.HSBCResponseCode = "";
            payment.DateActivated = DateTime.Now;
            payment.PaymentString = "Payment";
            payment.PromotionalOfferId = 1;
            payment.PaymentStatusId = (int)eNums.PaymentStatus.Paid;

            //payment.PaymentId = 1;

            dbEntities.AddToPayments(payment);
            dbEntities.SaveChanges();
        }
        return true;
    }

这个schema是:

enter image description here

15个回答

194

你有没有可能在表格之间定义了错误的列关系?

就我个人而言,我的表格中有不同的列,并且其中一个被设置为自动数字。


65
我错误地将一个外键设置为自增(Identity)了。这是我收到的错误信息。 - jocull
3
哎呀!我忘记修改外键关系的默认设定,这个默认是由 SQL Server 2008 Management Studio 给出的,它使用了子表的主键字段而不是我创建的用于存储外键值的列。请帮我翻译一下。 - robaker
13
如果您在“快速监视”窗口中检查异常(即(e as System.Data.Entity.Infrastructure.DbUpdateException).Entries),则可以看到包含所引用主键的表。 - Cᴏʀʏ
19
如果EF错误信息直接说明问题而不是输出无意义的内容,那不是很酷吗? - A.R.
1
我使用了这个查询来在一个视图中查看所有的关系: https://dev59.com/d2sz5IYBdhLWcg3wJUYo - Dave
显示剩余2条评论

48

这个错误提示表明你正在使用不支持的关系或者在映射过程中出现了错误。很可能,与此错误相关的代码与这个错误完全无关。

这个错误意味着你在实体之间建立了某种关系,其中从属实体的外键属性被定义为存储生成的属性。存储生成的属性是在数据库中填充的。EF 不支持将存储生成的属性用作外键(以及主键中的计算属性)。


2
我可以在SQL Server中添加具有相同信息的行。当您说“存储生成”,您能举个例子吗? - Welsh King
1
EF不是SQL Server,它有自己的限制。只需查找您使用任何DB生成的FK属性称为“PaymentID”的位置并处理它。 - Ladislav Mrnka
好的,我们有一个paymenthistory表,其中paymentId是外键,我需要在里面添加一行吗? - Welsh King
刚刚在 Visual Studio 中点击了关系模型,结果出现了“名称 'Payment' 不能用于类型 'Payment'。成员名称不能与其封闭类型相同”的错误提示。有什么想法吗? - Welsh King
它说属性不能与定义它的类型同名。看起来你的模型是无效的。 - Ladislav Mrnka
显示剩余6条评论

9
我遇到了相同的问题。基于此处所提供的答案,我成功地追踪并解决了问题,但我还有一个奇怪的问题,如下所述——这可能会帮助将来遇到类似问题的人。
在我的从属表中,外键列已经被设置为StoreGeneratedPattern="Identity"。我不得不把它改为“None”。不幸的是,在设计器内这样做根本行不通。
我查看了设计器生成的XML(SSDL),发现这些属性仍然存在,因此我手动删除了它们。我还必须修复数据库上的列(从CREATE TABLE SQL中删除Identity(1,1))。
之后,问题就消失了。

感谢这个提示。在设计器中将字段从Identity更改为None只更改了EDMX中的一个位置,而不是另一个位置,因此直到我自己编辑EDMX文件之前,我仍然会收到错误。不幸的是,EntityFramework随后疯狂地尝试重新插入其他表中的相关实体,但仍然有助于绕过该错误消息。 - FTWinston

8

我曾经遇到同样的问题,在深入研究了SQL Server中的表设计后,我发现错误地将表的主键也设置为了外键。

sql server table design flow

从这张图片中可以看出,JobID是表的主键,但也错误地成为了外键。


一个列既是主键又是外键是可以的,但如果这不是有意为之的话,就可能会引入意想不到的问题。如果Job被其他东西所引用,那么关系的PK表需要是Job,而且PK也是FK会成为一个问题,正如我们在这里看到的。如果Job是其他表的子表或子项,则PK + FK模式是正确的。因此,如果您有一个名为JobCertificate的表,那么它可能会这样做,并且依赖于Job,这是可以接受的,因为Job是父表,而JobCertificate是子表,并且没有Identity Specification on JobID。 - Tim

2

我的问题是由于在配置中多次定义主键导致的。

this
   .Property(p => p.Id)
   .HasColumnName(@"id")
   .IsRequired()
   .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity) // this is redundant when you want to configure a One-to-Zero-or-One relationship
   .HasColumnType("int");

请删除此行

.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity) // 设置自增长


示例http://www.entityframeworktutorial.net/code-first/configure-one-to-one-relationship-in-code-first.aspx

以上内容已足够定义关系

// Configure Student & StudentAddress entity
modelBuilder.Entity<Student>()
            .HasOptional(s => s.Address) // Mark Address property optional in Student entity
            .WithRequired(ad => ad.Student); // mark Student property as required in StudentAddress entity. Cannot save StudentAddress without Student

1
重新检查Payment和其他表/实体之间的关系,包括那些不应该包含PaymentId的表,因为问题很可能隐藏在那里。
在SQL Server Management Studio中创建外键时,默认使用主键,当更改父表时会恢复此默认设置,因此要小心按正确顺序更改“表和列”窗口中的值。
另外,在修复有问题的关系之后,很有可能简单的“刷新”模型无法正确地从模型中删除错误的关系,即使在“修复”之后也会出现相同的错误,所以在执行刷新之前自己在模型中进行操作。(我是通过艰难的方式发现的。)

1
在我的情况下,Entity Framework 中的外键 Id 字段的 "StoreGeneratedPattern" 属性被设置为 "Identity" 而不是 "None"。

1
如果你已经检查了你的关系并且没有问题,那么请删除edmx中的表格,然后从数据库更新。这样可以避免手动进行更新。

非常感谢您的建议,我花了1个小时来验证我的数据库,但是在删除后更新之后,一切都正常了。 - Tấn Nguyên

1
对我来说,这是数据表中错误放置的外键,但即使修改了表以修复它,仍然无法工作。您需要更新EDMX文件(不仅仅是从模型“刷新”表格,而是需要在模型中删除并重新添加表格)。

1
除了被接受的答案之外,如果您正在使用EF Reverse POCO生成器或其他生成POCO的工具,请确保您重新生成它们!

永远不要忘记在修改外部DB-first EF模型生成器(持有上下文)后重新运行您的自定义T4工具(持有POCOs)... 永远!XD(也可能会变得疯狂-.-') - Shockwaver

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接