C#,entity framework,自动增量
我正在学习VC#2010下的entity framework。
我创建了一个用于学习目的的简单表,其中一个字段是“id”类型整数,标识设置为true。 我已从该表生成实体数据模型并将其与dataGridView连接。 问题是它不会自动递增 – 每个插入的行都想成为id = 0(当然,这是不可能的,因为id必须是唯一的)
我究竟做错了什么? 我应该如何配置EF或SQL db本身?
检查您的EDMX模型,自动增量字段的StoreGeneratedPattern属性设置为“Identity”。 通过这种方式,EF知道自动程序由DB处理。
这里更好地解释了: 使用entity framework的自动编号
仅通过添加到实体集来设置和增加标识…实体实际上不会保存到数据库,直到您调用context.SaveChanges()…
db.AddToUserSet(user);//Added to EF entity collection db.SaveChanges();//INSERT executed in db, Identity set and incremented.
在尝试读取自动递增的Id值之前,请确保将实体保存回数据库。
在第一次将其实际保存到数据库之前,不会通过自动递增来设置您的ID。
是。 LINQ to SQL的行为方式相同。 在将ID保存到数据库之前,不会设置该ID。 在你这样做之前,所有的id都将为零(正如你已经看到的那样)。
我有类似的问题,发生在EF6(在没有事务的情况下在EF4中工作,EF 4使用了具有正确范围的隐式事务)。
只是创建一个新实体并保存它在我的情况下没有帮助(参见其他答案的注释,他们在使用dc.SaveChanges()
只有自动更新的类似问题)。
请考虑以下代码( CustomerId
是具有自动增量的主键):
public void UpdateCustomer(string strCustomerName, string strDescription) { using (var transaction = CreateTransactionScope()) { MyCustomer tbl=null; Func 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
。
要了解有关事务范围的更多信息,请查看此处