EF Code First Modelbuilder创建不应该使用的唯一标识符

时间:2012-12-28 16:47:56

标签: asp.net-mvc entity-framework ef-code-first

我有这样的事情:

modelBuilder.Entity<TransactionHistory>()
                .HasOptional(history => history.Sender)
                .WithMany()
                .Map(s => s.MapKey("Sender"))
                .WillCascadeOnDelete(false);

modelBuilder.Entity<TransactionHistory>()
                .HasOptional(history => history.Receiver)
                .WithMany()
                .Map(s => s.MapKey("Receiver"))
                .WillCascadeOnDelete(false);

在我的表TransactionHistory中,它在Sender和Receiver列创建唯一标识符。我不希望这些列是唯一的,我该怎么办?

TransactionHistory模型:

public class TransactionHistory
    {
        public Account Sender { get; set; }
        public Account Receiver { get; set; }
    }

编辑:好的。显然,独特的标识符并非如此。问题是,当我将transactionhistory项添加到数据库时,我收到以下错误:

  

违反PRIMARY KEY约束'PK_dbo.Accounts'。无法插入   对象'dbo.Accounts'中的重复键。\ r \ n声明已经存在   终止。

我添加这样的项目:

context.Transactions.Add(history);
context.savechanges();

(交易是一个交易历史对象)

2 个答案:

答案 0 :(得分:2)

EF使用uniqueidentifier作为外键的SQL列类型,因为主体的(= Account s)主键是uniqueidentifier - 在C#中它是Guid ,如public Guid AccountId { get; set; }

必须选择此类型,因为主键和从属键类型必须在数据库中的外键关系中匹配。

这并不意味着外键列是唯一的(或具有唯一索引)。当然,您可以多次使用与外键列值相同的uniqueidentifier值。

答案 1 :(得分:1)

实体框架通过在DBContext中存储一堆对象的缓存来工作。即使您的Account对象(包括您的pk)上的所有属性都相同,实体框架也会将此视为一个新对象,除非您提醒它“嘿,您已经知道这个”。我可以想到两种方法:

context.Entry(history.Sender).State = EntityState.Modified; 
context.Entry(history.Receiver).State = EntityState.Modified; 

确保在历史记录对象上设置“帐户”时,它们已附加到dbcontext。

var sender = context.Accounts.FirstOfDefault(...your condition here...);
var receiver = context.Accounts.FirstOfDefault(...your condition here...);

history.Sender = sender;
history.Receiver = receiver;

除非您告知,否则EF不会加载导航/相关实体。因此,如果您正在编辑历史记录,请确保使用.Include()来提取相关对象。

希望有所帮助。