我正在學習實體框架下,VC#2010C#,實體框架,自動增加
我創建了一個簡單的表,學習之用,其中一個字段是「ID」整數類型,標識設置爲true 。我從該表生成了實體數據模型,並將其與dataGridView連接起來。問題是,它不會自動增加 - 每個插入的行要成爲ID = 0(這是不可能的,當然,因爲ID必須是唯一的)
我在做什麼錯?我應該如何配置EF或SQL數據庫本身?
我正在學習實體框架下,VC#2010C#,實體框架,自動增加
我創建了一個簡單的表,學習之用,其中一個字段是「ID」整數類型,標識設置爲true 。我從該表生成了實體數據模型,並將其與dataGridView連接起來。問題是,它不會自動增加 - 每個插入的行要成爲ID = 0(這是不可能的,當然,因爲ID必須是唯一的)
我在做什麼錯?我應該如何配置EF或SQL數據庫本身?
檢查您的EDMX模型,將自動增量字段的StoreGeneratedPattern屬性設置爲「Identity」。通過這種方式,EF知道自動編號由DB處理。
這裏是這樣解釋更好:Autonumber with Entity Framework
確保你保存實體回數據庫嘗試讀取自動遞增的標識值之前。
您的身份不會被自動增量第一次它實際上是保存到數據庫中,直到集。
的問題是,在調用的SaveChanges(添加多行後),它將引發有關複製主鍵... – migajek 2010-07-06 16:48:39
@vic一個例外 - 有趣的。你確定自動遞增鍵表的插入失敗嗎? – 2010-07-06 16:51:06
是的。 LINQ to SQL的行爲方式相同。該ID在被保存到數據庫之前不會被設置。在你做之前,所有的ID都是零(如你已經看到的)。
身份不設置和增加只是通過向實體集... 實體實際上不是保存到數據庫,直到調用context.SaveChanges()...
db.AddToUserSet(user);//Added to EF entity collection
db.SaveChanges();//INSERT executed in db, Identity set and incremented.
的問題是,在調用的SaveChanges(添加多行後),它將引發有關複製主鍵異常... – migajek 2010-07-06 16:48:59
我有類似的問題,這發生在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.
呀一般從VS2010產生的碎片,你將不得不設置StoreGenerated價值XML的頂部大塊。您正在獲取多個主鍵,因爲除非您更改該鍵,否則EF會爲您生成ID,爲0。 – Rangoric 2010-07-07 17:19:19
他們還沒有解決這個無處不在的錯誤,這真是瘋狂。這是第4版,加入EF團隊! – arviman 2011-07-15 22:03:35
很多時候,人們忘記用標識和自動增量值來標記列。 EF確實從數據庫中選擇了這一點。 – arviman 2012-03-15 18:04:57