2016-03-02 62 views
0

我目前正在使用实体Framwork 6 一个新的ASP.NET MVC应用我有2班它们一起工作:帐户和AccountAddition。 帐户代表基本用户帐户和AccountAddition包含联系人,通知或上次登录的时间的例子ICollections。实体框架添加对象集合导致意外的行为

现在我只是想通过curAcc.Addition.Contacts.Add(correspondingAccount)添加一个新的帐户AccountAdditions ICollection的联系人属性,其中correspondingAccount是帐户要添加的对象(这两个帐户在数据库中给出)。

问题是,当我将correspondingAccount添加到当前帐户的联系人时,参考correspondingAccount.Addition突然指向当前帐户的AccountAddition

问题的一部分:

... 
Account curAcc = context.Accounts.FirstOrDefault(p => p.Alias == currentAlias); 
     if(ModelState.IsValid) 
     { 
      var correspondingAccount = context.Accounts.FirstOrDefault(p => p.Alias == addAlias); 
      if(correspondingAccount != null) 
      { 
       curAcc.Addition.Contacts.Add(correspondingAccount); 
       context.SaveChanges(); 
       ... 

代码第一类:

public class Account 
{ 
    public Account() 
    { 
     IsEnabled = true; 
    } 
    [Key] 
    public int ID { get; set; } 
    public string Alias { get; set; } 
    [DataType(DataType.Password)] 
    public string Password { get; set; } 
    public byte[] Salt { get; set; } 

    [ForeignKey("Config")] 
    public int ConfigID { get; set; } 
    public virtual CryptoConfig Config { get; set; } 
    [ForeignKey("Addition")] 
    public int AdditionID { get; set; } 
    public virtual AccountAddition Addition { get; set; } 
    public virtual ICollection<AccountRoleLink> Roles { get; set; } 
    public bool IsEnabled { get; set; } 
} 

public class AccountAddition 
{ 
    public AccountAddition() 
    { 
     CreatedOn = DateTime.Now; 
     Contacts = new List<Account>(); 
     Notifications = new List<Notification>(); 
    } 
    [Key] 
    public int ID { get; set; } 
    public virtual ICollection<Account> Contacts { get; set; } 
    public virtual ICollection<Notification> Notifications { get; set; } 
    public string ContactEmail { get; set; } 

    public Nullable<DateTime> LastLogin { get; set; } 
    public Nullable<DateTime> LastFailedLogin { get; set; } 
    public Nullable<DateTime> CreatedOn { get; set; } 
} 

更多例子:

Account curAcc = // Find current account (current context) 
Account correspondingAcc = // Get account to add (same context) 

curAcc.Addition is Addition with id 1 
correspondingAcc.Addition is Addition with id 2 
// correspondingAcc gets added via curAcc.Addition.Contacts.add(cor...) 
// context saves changes 
curAcc.Addition is Addition with id 2 afterwards 
correspondingAcc.Addition is Addition with id 2 afterwards 

我试着用搜索引擎和EF教程搜索,但没有找到解决办法。 有什么不对?

感谢您的时间

UPDATE:

好显然是ODY所提供的解决方案并没有达到预期效果。 我试图从通知和联系人的集合中删除虚拟关键字。 的文档片断,现在看起来是这样的:Add方法被调用时,context.Accounts帐户对象指向错误AccountAddition后

Account curAcc = GetCurrentAccount(); 
     if(ModelState.IsValid) 
     { 
      var correspondingAccount = context.Accounts.FirstOrDefault(p => p.Alias == addAlias); 
      if(correspondingAccount != null) 
      { 
       curAcc.Addition.Contacts.Add(correspondingAccount); 

       var existingCorrespondingAccount = curAcc.Addition 
             .Contacts.Where(a => a.Alias == addAlias) 
             .FirstOrDefault(); 
       if (existingCorrespondingAccount != null) 
       { 
        context.Accounts.Add(curAcc); 
       } 


       context.SaveChanges(); 

权。当我想将帐户f2(AdditionId 2)添加到帐户f1(AdditionId 1)时,f2的addId指向1.

当我调用SaveChanges时,会引发System.Data.Entity.Infrastructure.DbUpdateException。

{“保存不会为其关系公开外键属性的实体时发生错误EntityEntries属性将返回null,因为无法将单个实体标识为异常的来源。可以制成通过在实体类型暴露的外键的属性更容易。详情请参阅的InnerException。“}

内部异常是

{”商店更新,插入或删除语句影响的unexp行数(0)。自实体加载后,实体可能已被修改或删除。见http://go.microsoft.com/fwlink/?LinkId=472540的信息,理解和处理乐观并发异常。“}

我跟着链接,并试图抓住它使用OptimisticConcurrencyException和DbUpdateConcurrencyException,但EX是DbUpdateException这是不被他们逮住。

这是令人沮丧:(

+0

你有EF全球语境? – Lance

+0

Hello Lance,我的上下文在基础控制器类中给出。 公共抽象类BaseController:控制器 { protected MyDbContext context = new MyDbContext(); – Gurken

回答

0

的问题是无论何时您将一个实体添加到相关的财产集合并致电SaveChanges(),它都不检查该ID是否已经存在,它会创建一个新的实体,这就是EF的工作原理。 ,y ou应在使用ID手动添加帐户之前检查帐户是否已存在于acc.Contacts中。

像这样的事情

Account curAcc = context.Accounts.FirstOrDefault(p => p.Alias == currentAlias); 
var correspondingAccount = context.Accounts.FirstOrDefault(p => p.Alias == addAlias); 
if (correspondingAccount != null) 
{ 
    curAcc.Addition.Contacts.Add(correspondingAccount); 

    var existingCorrespondingAccount = curAcc.Addition 
              .Contacts.Where(a => a.Alias == addAlias) 
              .FirstOrDefault(); 
    if(existingCorrespondingAccount != null) 
    { 
      context.Accounts.Add(new Account 
      { 
       AdditionID = curAcc.AdditionID, 
       Alias = curAcc.Alias, 
       ConfigID = curAcc.ConfigID, 
       IsEnabled = curAcc.IsEnabled, 
       Password = curAcc.Password, 
       Salt = curAcc.Salt 
      }); 
    } 
    context.SaveChanges(); 
} 
+0

这引发了一个OptimisticConcurrencyException。 inner:{“存储更新,插入或删除语句会影响意外数量的行(0)。实体可能已被修改或删除,因为实体已加载。请参阅http://go.microsoft.com/fwlink/?LinkId= 472540了解和处理乐观并发异常的信息。“}。我会检查,但我感谢更多的帮助。 :)感谢迄今,现在我必须明白为什么EF做它在做什么 – Gurken

+0

好的,问题没有解决。更新问题 – Gurken

+0

该异常可能是由于curAcc的ID属性。所以你的插入应该是没有ID属性的curAcc的副本。我更新了答案以反映这 – Ody