我正在学习VC#2010下的实体框架。
我创建了一个用于学习目的的简单表,其中一个字段是“id”类型整数,标识设置为true。我已从该表生成实体数据模型并将其与dataGridView连接。问题是它不会自动递增 - 每个插入的行都想成为id = 0(当然,这是不可能的,因为id必须是唯一的)
我做错了什么?我应该如何配置EF或SQL db本身?
答案 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.