我有这样的事情:
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();
(交易是一个交易历史对象)
答案 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()来提取相关对象。
希望有所帮助。