C# Linq to实体有时会将重复条目插入数据库

C# Linq to实体有时会将重复条目插入数据库,c#,entity-framework,asp.net-mvc-4,C#,Entity Framework,Asp.net Mvc 4,下面的代码用于向数据库中添加一行或更新已有的行 IEnumerable<Guid> fieldIds = glen.ComplianceField.Select(field => field.id); ComplianceData data; foreach (Guid fieldId in fieldIds) { if (!checkEntity(fieldId, Extra.grn)) { if (collection[fieldId.ToS

下面的代码用于向数据库中添加一行或更新已有的行

IEnumerable<Guid> fieldIds = glen.ComplianceField.Select(field => field.id);
ComplianceData data;
foreach (Guid fieldId in fieldIds)
{
    if (!checkEntity(fieldId, Extra.grn))
    {
        if (collection[fieldId.ToString()] != null)
        {
            if (glen.ComplianceData.Where(compData => (compData.fieldId == fieldId) && (compData.grn == Extra.grn)).Count() == 0)
            {
                data = new ComplianceData();
                glen.ComplianceData.Add(data);
            }
            else
                data = glen.ComplianceData.First(compData => (compData.fieldId == fieldId) && (compData.grn == Extra.grn));
            data.fieldId = fieldId;
            data.grn = Extra.grn;
            data.value = collection[fieldId.ToString()];
        }
    }
}
glen.SaveChanges();
IEnumerable fieldid=glen.ComplianceField.Select(field=>field.id);
顺应性数据;
foreach(fieldId中的Guid fieldId)
{
如果(!checkEntity(fieldId,Extra.grn))
{
if(集合[fieldId.ToString()]!=null)
{
如果(glen.ComplianceData.Where(compData=>(compData.fieldId==fieldId)&(compData.grn==Extra.grn)).Count()==0)
{
数据=新的合规性数据();
格伦合规性数据添加(数据);
}
其他的
data=glen.ComplianceData.First(compData=>(compData.fieldId==fieldId)和&(compData.grn==Extra.grn));
data.fieldId=fieldId;
data.grn=Extra.grn;
data.value=集合[fieldId.ToString()];
}
}
}
格伦·萨维Changes();
但是,有时(我怀疑如果用户多次单击提交按钮),数据库中的行会重复(如果服务器速度特别慢,则会重复多次)。此问题仅在首次创建条目时发生,之后将按预期更新第一个条目


我尝试过使用上下文的ChangeTracker属性,但我怀疑这不起作用,因为glen上下文在每个后续请求中都是不同的对象。是否有一种方法可以在执行操作时锁定数据库表,或者在刚刚发出相同的请求时阻止该操作执行数据库更新?

如果您怀疑是由于多次单击某个按钮导致的,则可以采取各种步骤来停止此操作,例如在按钮被选中后立即禁用该按钮激活。您还应该进行一些服务器端检查,以确保没有收到多个请求。

我最终使用
System.Transactions实现了这一点(我必须添加一个新的引用才能访问它)。我的最后一个片段是-

IEnumerable<Guid> fieldIds = glen.ComplianceField.Select(field => field.id);
ComplianceData data;
    using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.Serializable}))
        {
            foreach (Guid fieldId in fieldIds)
            {
                if (collection[fieldId.ToString()] != null)
                {
                    if (glen.ComplianceData.Where(compData => (compData.fieldId == fieldId) && (compData.grn == Extra.grn)).Count() == 0)
                    {
                        data = new ComplianceData();
                        glen.ComplianceData.Add(data);
                    }
                    else
                        data = glen.ComplianceData.First(compData => (compData.fieldId == fieldId) && (compData.grn == Extra.grn));
                        data.fieldId = fieldId;
                        data.grn = Extra.grn;
                        data.value = collection[fieldId.ToString()];
                }
            }
            glen.SaveChanges();
            scope.Complete();
        }
IEnumerable fieldid=glen.ComplianceField.Select(field=>field.id);
顺应性数据;
使用(TransactionScope作用域=新建TransactionScope(TransactionScopeOption.Required,新建TransactionOptions{IsolationLevel=System.Transactions.IsolationLevel.Serializable}))
{
foreach(fieldId中的Guid fieldId)
{
if(集合[fieldId.ToString()]!=null)
{
如果(glen.ComplianceData.Where(compData=>(compData.fieldId==fieldId)&(compData.grn==Extra.grn)).Count()==0)
{
数据=新的合规性数据();
格伦合规性数据添加(数据);
}
其他的
data=glen.ComplianceData.First(compData=>(compData.fieldId==fieldId)和&(compData.grn==Extra.grn));
data.fieldId=fieldId;
data.grn=Extra.grn;
data.value=集合[fieldId.ToString()];
}
}
格伦·萨维Changes();
scope.Complete();
}

部分原因在于这个答案

如果该代码段从不同的线程运行,您将得到这样的行为。您必须同步您的代码。此外,您还必须向数据库添加一些完整性约束。我已经意识到我可以阻止此客户端,但我正在寻找一种方法,如您所说,检查多个请求是否未通过。我将更新我的问题以反映这一点。