2011-09-19 56 views
0

一个保存()函数插入/更新我有一个街道表,其中有作为的PK,是邮递区号和streetcode两个String列的组合。EF4.1的DbContext:在没有身份PK

随着EF4.1和的DbContext,我想编写一个“保存”方法比采用一条街(即将在未附着状态),检查是否已经存在于数据库中。如果这样做,问题的最新情况,如果没有,它会发出一个INSERT。

仅供参考,可以节省这些街道的应用,从文本文件阅读他们,拯救他们(有没有几万在该文件中,这些“streetlines”的)。

我想出现在是:

public void Save(Street street) 
    { 
     var existingStreet = (
           from s in streetContext.Streets 
           where s.PostalCode.Equals(street.PostalCode) 
           && s.StreetCode.Equals(street.StreetCode) 
           select s 
          ).FirstOrDefault(); 

     if (existingStreet != null) 
      this.streetContext.Entry(street).State = System.Data.EntityState.Modified; 
     else 
      this.streetContext.Entry(street).State = System.Data.EntityState.Added; 

     this.streetContext.SaveChanges(); 
    } 

这是很好的做法?这里的表现如何?因为每一条街道都会首先进行数据库往返查看它是否存在。

尝试插入街道(state = added)并捕获任何PK违规行为会不会更好?在catch块,然后我可以改变状态,以修改和()再次调用的SaveChanges。或者这不是一个好的做法?

有什么建议?

感谢

回答

1

感谢您的答复,但没有人真的满意,所以我做了一些更多的研究,并重写了这样的方法,这符合我的需要。

PS:改名的方法导入(),因为我发现了一个用于(散装)从外部导入的实体(如在我的情况下,文本文件)

PS2的方法更合适的名称:我知道,最好的做法是赶上一个例外,让它不做任何事情就默默地死去,但在我的特殊情况下,我没有必要对它做任何事情。它只是作为一种方法来发现该行已经存在于数据库中。

public void Import(Street street) 
{ 
     try 
     { 
      this.streetContext.Entry(street).State = System.Data.EntityState.Added; 

      this.streetContext.SaveChanges(); 
     } 
     catch (System.Data.Entity.Infrastructure.DbUpdateException dbUex) 
     { 
      this.streetContext.Entry(street).State = System.Data.EntityState.Modified; 

      this.streetContext.SaveChanges(); 
     } 
     finally 
     { 
      ((IObjectContextAdapter)this.streetContext).ObjectContext.Detach(street); 
     } 
} 
1

选择所有的街道,然后做一个对每个进行比较,并改变状态循环。循环完成后调用saveChanges。通过这种方式,您只需拨打一些电话给db而不是几个thousend

+0

谢谢,但不是真正的选择,我认为一次加载20K街道实体,性能明智 – tjeuten

0

如果街道已经存在于数据库中,则您的代码必须导致异常,因为您将从上下文中加载它,之后您将尝试附加另一个实例对同一个上下文实例使用相同的主键。

如果你真的要做到这一点使用此代码来代替:

public void Save(Street street) 
{ 
    string postalCode = street.PostalCode; 
    string streetCode = steet.StreetCode; 
    bool existingStreet = streetContext.Streets.Any(s => 
          s.PostalCode == postalCode 
          && s.StreetCode = steetCode); 

    if (existingStreet) 
     streetContext.Entry(street).State = System.Data.EntityState.Modified; 
    else 
     streetContext.Entry(street).State = System.Data.EntityState.Added; 

    streetContext.SaveChanges(); 
} 

反正它仍然不高并发系统的可靠解决方案,因为其他线程可以插入相同的街道之间你检查及后续插件。