2010-07-06 56 views
23

我正在学习实体框架下,VC#2010C#,实体框架,自动增加

我创建了一个简单的表,学习之用,其中一个字段是“ID”整数类型,标识设置为true 。我从该表生成了实体数据模型,并将其与dataGridView连接起来。问题是,它不会自动增加 - 每个插入的行要成为ID = 0(这是不可能的,当然,因为ID必须是唯一的)

我在做什么错?我应该如何配置EF或SQL数据库本身?

回答

35

检查您的EDMX模型,将自动增量字段的StoreGeneratedPattern属性设置为“Identity”。通过这种方式,EF知道自动编号由DB处理。

这里是这样解释更好:Autonumber with Entity Framework

+0

呀一般从VS2010产生的碎片,你将不得不设置StoreGenerated价值XML的顶部大块。您正在获取多个主键,因为除非您更改该键,否则EF会为您生成ID,为0。 – Rangoric 2010-07-07 17:19:19

+5

他们还没有解决这个无处不在的错误,这真是疯狂。这是第4版,加入EF团队! – arviman 2011-07-15 22:03:35

+1

很多时候,人们忘记用标识和自动增量值来标记列。 EF确实从数据库中选择了这一点。 – arviman 2012-03-15 18:04:57

1

确保你保存实体回数据库尝试读取自动递增的标识值之前。

您的身份不会被自动增量第一次它实际上是保存到数据库中,直到集。

+2

的问题是,在调用的SaveChanges(添加多行后),它将引发有关复制主键... – migajek 2010-07-06 16:48:39

+0

@vic一个例外 - 有趣的。你确定自动递增键表的插入失败吗? – 2010-07-06 16:51:06

1

是的。 LINQ to SQL的行为方式相同。该ID在被保存到数据库之前不会被设置。在你做之前,所有的ID都是零(如你已经看到的)。

2

身份不设置和增加只是通过向实体集... 实体实际上不是保存到数据库,直到调用context.SaveChanges()...

db.AddToUserSet(user);//Added to EF entity collection 
db.SaveChanges();//INSERT executed in db, Identity set and incremented. 
+6

的问题是,在调用的SaveChanges(添加多行后),它将引发有关复制主键异常... – migajek 2010-07-06 16:48:59

0

我有类似的问题,这发生在EF6(的确在EF4工作没有交易,EF 4使用权范围内隐交易)。

只是创建一个新的实体并保存它并没有帮助我的情况(请参阅其他答案的评论,他们在使用dc.SaveChanges()时也遇到了类似的问题,只能用于自动更新)。

考虑下面的代码(CustomerId是通过自动递增的主键):

public void UpdateCustomer(string strCustomerName, string strDescription) 
{ 
    using (var transaction = CreateTransactionScope()) 
    { 
    MyCustomer tbl=null; 
    Func<MyCustomer, bool> selectByName=(i => i.CustomerName.Equals(strCustomerName)); 
    var doesRecordExistAlready = dc.MyCustomers.Any(selectByName); 
    if (doesRecordExistAlready) 
    { 
     // Updating 
     tbl=dc.MyCustomers.Where(selectByName).FirstOrDefault();   
     tbl.Description=strDescription; 
    } 
    else 
    { 
     // Inserting 
     tbl=new MyCustomer(); 
     var maxItem= 
      dc.MyCustomers.OrderByDescending(i => i.CustomerId).FirstOrDefault(); 
     var newID = maxItem==null ? 1 : maxItem.CustomerId+1; 
     tbl.CustomerId=newID; 
     tbl.CustomerName=strCustomerName; 
     tbl.Description=strDescription; 
     dc.MyCustomers.AddObject(tbl);  
    } 
    dc.SaveChanges(); // save all changes consistently   
    transaction.Complete(); // commit 
    } 
} 

和辅助功能,营造合适的事务上下文:

// creates the right transaction scope 
public static System.Transactions.TransactionScope CreateTransactionScope() 
    // needs to add ref: System.Transactions 
{ 
    var transactionOptions = new TransactionOptions 
    { 
     IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted, 
     Timeout = new TimeSpan(0,0,10,0,0) //assume 10 min is the timeout time 
    }; 
    var scopeOption=TransactionScopeOption.RequiresNew; 
    var scope = new System.Transactions.TransactionScope(scopeOption, 
       transactionOptions); 
    return scope; 
} 

诀窍是这里,允许读取未提交 - 因此您可以查询最大ID并将ID添加1。我无法实现的是让SQL服务器自动生成ID,因为EF允许我在创建时不要忽略CustomerId

想了解更多关于交易的范围,look here.