如何使用linq从表中获取最大id

时间:2018-02-02 06:39:27

标签: c# linq entity-framework-6

我有一个表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

现在,如何处理这个问题..请给出一些解决方案。

5 个答案:

答案 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