[英]Entity Framework baseline integrity
我首先使用Entity Framework數據庫,並且有一個表使用基線ID存儲歷史值。 我們使用基線ID在此表上存儲父/子鏈接。 以下專欄對此設計進行了補充:-
為清楚起見示例數據
Id BaselineId ParentBaselineId Latest
1 1 NULL 0
2 1 NULL 1
3 2 1 0
4 2 1 1
這顯示了兩個項目,每個項目都有兩個修訂版本。 基准1是基准2的父級。
我的問題是,出於下面列出的原因,我在C#中查找了下一個可用基線,並手動指定了要保存的BaselineId / ParentBaselineId。 當兩個用戶同時觸發此方法時,他們將保存相同的基准ID,因為在第二個用戶查找下一個可用的基准ID之前,保存尚未完成。
我應該采取什么措施來確保兩個用戶同時運行該方法不會使用相同的基線?
我的C#看起來像這樣
using (var tx = new TransactionScope())
{
using (var context = new DbContext(connectionString))
{
int baseline = context.MyTable.Max(e => e.BaselineId);
context.MyTable.Add(new MyTable() {BaselineId = baseline + 1, Latest = true});
context.MyTable.Add(new MyTable() { BaselineId = baseline + 2, ParentBaselineId = baseline + 1, Latest = true });
context.SaveChanges();
}
tx.Complete();
}
根據@Steve Greene的建議,我可以使用SQL序列。 在數據庫中創建新序列並設置起始值以匹配現有數據后,我將代碼更新為以下內容。
public long NextBaseline(DbContext context)
{
DataTable dt = new DataTable();
var conn = context.Database.Connection;
var connectionState = conn.State;
try
{
if (connectionState != ConnectionState.Open)
conn.Open();
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "SELECT NEXT VALUE FOR MySequence;";
using (var reader = cmd.ExecuteReader())
{
dt.Load(reader);
}
}
}
catch (Exception ex)
{
throw new HCSSException(ex.Message, ex);
}
finally
{
if (connectionState != ConnectionState.Open)
conn.Close();
}
return Convert.ToInt64(dt.AsEnumerable().First().ItemArray[0]);
}
public void Save()
{
using (var tx = new TransactionScope())
{
using (var context = new DbContext(connectionString))
{
var parent = new MyTable() { BaselineId = NextBaseline(context), Latest = true };
var child = new MyTable() { BaselineId = NextBaseline(context), ParentBaselineId = parent.BaselineId, Latest = true }
context.MyTable.Add(parent);
context.MyTable.Add(child);
context.SaveChanges();
}
tx.Complete();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.