C#,实体框架,自动增量

时间:2010-07-06 16:28:54

标签: c# entity-framework

我正在学习VC#2010下的实体框架。

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

我做错了什么?我应该如何配置EF或SQL db本身?

5 个答案:

答案 0 :(得分:37)

签入您的EDMX模型,自动增量字段的StoreGeneratedPattern属性设置为“Identity”。通过这种方式,EF知道自动程序由DB处理。

这里有更好的解释:Autonumber with Entity Framework

答案 1 :(得分:2)

仅通过添加到实体集来设置和增加标识... 在调用context.SaveChanges()...

之前,实体实际上并未保存到数据库中
db.AddToUserSet(user);//Added to EF entity collection
db.SaveChanges();//INSERT executed in db, Identity set and incremented.

答案 2 :(得分:1)

在尝试读取自动递增的Id值之前,请确保将实体保存回数据库。

在第一次将数据库实际保存到数据库之前,不会通过自动递增来设置您的ID。

答案 3 :(得分:1)

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

答案 4 :(得分: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并将1添加到id。我无法实现的是让SQL服务器自动生成ID,因为EF允许我在创建时不要省略CustomerId

要详细了解交易范围,look here.