我有一个表Estimation有一个EstimationNo列,我试图得到最大的EstimationNo这样 -
var result = cont.SalesEstimateCont.Where(x => x.Org_ID == CurrentOrgId);
var estimationMaxNo = result.Any() ? result.Max(x => x.EstimateNo) + 1 : 1;
var DigitalEstimate = new SalesEstimate()
{
EstimateNo=estimationMaxNo;
};
cont.Estimate.Add(DigitalEstimate );
cont.Savechanges();
但问题是,如果同一个表同时由不同的用户保存,则为两个用户保存相同的EstimationNo。喜欢-10,10
现在,如何处理这个问题..请给出一些解决方案。
答案 0 :(得分:1)
最佳策略是让db引擎(我假设它是SQL Server)处理递增EstimateNo字段。这可以使用identity规范来完成,该规范也可以添加到普通not primary key字段中。
ALTER TABLE SalesEstimateCont drop column EstimateNo
go
ALTER TABLE SalesEstimateContadd Add EstimateNo int NOT NULL IDENTITY (1,1)
请注意:如果您有现有数据或某些数据应该被修改,您可能需要额外的努力来实现这一点(即使用临时表并设置IDENTITY INSERT ON)
答案 1 :(得分:1)
我得到了一个简单的答案。我只需要使用transacationScope类。 并锁定资源表。 喜欢这样 -
using (TransactionScope scope = new TransactionScope())
{
cont.Database.ExecuteSqlCommand("SELECT TOP 1 * FROM Sales__Estimate WITH (TABLOCKX, HOLDLOCK)");
var result = cont.SalesEstimateCont.Where(x => x.Org_ID == CurrentOrgId);
var estimationMaxNo = result.Any() ? result.Max(x => x.EstimateNo) + 1 : 1;
var DigitalEstimate = new SalesEstimate()
{
EstimateNo=estimationMaxNo;
};
cont.Estimate.Add(DigitalEstimate );
cont.Savechanges();
}
答案 2 :(得分:1)
如果您可以将EstimateNo设为Identity列,那么这是解决此问题的最简单/最佳方法。如果您可以将其更改为Guid,那么这将是解决此问题的另一种简单方法,因为无论用户如何,PK都是唯一的。
如果您无法执行其中任何一项并且必须手动使用Max(),则可能需要考虑创建另一个存储下一个可用数字的表。然后,您可以使用Serializable事务创建一个新的SqlCommnand来锁定表,更新#by 1并选择它。如果两个更新命令同时命中,则只有一个更新将运行,并且在与Serializable事务的连接关闭之前不会放弃。这允许您在另一个更新运行之前选择新更新的数字,并获得现在“唯一”的下一个数字。
答案 3 :(得分:-1)
您可以OrderByDescending
然后Take
第一条记录
var estimationMaxNo = result.OrderByDescending(x => x.EstimateNo).Take(1);
答案 4 :(得分:-3)
可以在一个命令中完成。您需要为主ID
设置IDENTITY属性ALTER TABLE SalesEstimateCont ADD Org_ID int NOT NULL IDENTITY (1,1) PRIMARY KEY