在将实体保存到数据库之前,我需要检查重复的条目。以下是我目前的代码
if (db.Product.Any(x => x.Code == entity.Code))
{
error.Add('Duplicate code');
}
if (db.Product.Any(x => x.Name == entity.Name))
{
error.Add('Duplicate name');
}
if (db.Product.Any(x => x.OtherField == entity.OtherField))
{
error.Add('Duplicate other field');
}
上面代码的问题是它对验证实体进行了3 db调用。这个表有数百万条记录,这个应用程序将被千名用户使用。所以它会严重损害性能。我可以通过
进行一次查询if (db.Product.Any(x => x.Code == entity.Code || x.Name == entity.Name || x.OtherField == entity.OtherField))
{
error.Add('Duplication found');
}
第二个代码的问题是我不知道哪个字段是重复的。
这样做的更好方法是什么?我应该只依赖数据库中的唯一约束吗?但是,数据库中的错误很难看。
修改
如果超过1个重复字段,我需要向用户显示所有错误。 考虑这种情况:如果重复的字段是代码和名称。如果我告诉用户代码已经存在,那么他会更改代码并尝试再次保存。然后显示第二个错误(名称字段)。在成功保存之前,它会使用户点击保存几次。
答案 0 :(得分:2)
如果您在字段Name
,Code
和OtherField
上有索引,则重复检查不会太长,但仍会是对数据库的3次调用,而不是1次。
在这种情况下,通常的解决方案是重复计算。然后,如果count等于0,则不会重复。
Here你会发现一些黑客攻击。
简短的例子:
var counts =(
from product in db.Products
group product by 1 into p
select new
{
Name = p.Count(x => x.Name == name),
Code = p.Count(x => x.Code == code),
OtherField = p.Count(x => x.OtherField == otherFields)
}
).FirstOrDefault();
if (counts.Name > 0)
error.Add("Duplicate name");
if (counts.Code > 0)
error.Add("Duplicate code");
更新:似乎可以通过更简单的方法解决问题:
var duplicates =(
from product in db.Products
group product by 1 into p
select new
{
Name = p.Any(x => x.Name == name),
Code = p.Any(x => x.Code == code),
OtherField = p.Any(x => x.OtherField == otherFields)
}
).FirstOrDefault();
if (duplicates.Name)
error.Add("Duplicate name");
答案 1 :(得分:1)
您可以这样做:
string duplicateField;
bool validationResult = db.Product.Any(x => {
if(x.Code == entity.Code){
duplicateField = "Code";
return true;
}
// Other field checks here
}
if(validationResult){
// Error in field <duplicateField>
}
答案 2 :(得分:0)
1-您可以选择重复实体
var product = db.Product.FirstOrDefault(x => x.Code == entity.Code
|| x.Name == entity.Name
|| x.OtherField == entity.OtherField);
if (product == null)
;//no duplicates
if (product.Code == entity.Code)
{
error.Add('Duplicate code');
}
if (product.Name == entity.Name)
{
error.Add('Duplicate name');
}
if (product.OtherField == entity.OtherField)
{
error.Add('Duplicate other field');
}
2-您可以创建插入的存储过程并检查其中的重复项;
编辑: 好的,你可以写这样的东西
var duplicates = (from o in db.Products
select new
{
codeCount = db.Products.Where(c => c.Code == entity.Code).Count(),
nameCount = db.Products.Where(c => c.Name == entity.Name).Count(),
otherFieldCount = db.Products.Where(c => c.OtherField == entity.OtherField).Count()
}).FirstOrDefault();
这将按字段选择每个重复的数量。 有一点需要注意:无论如何,您应该在数据库中有唯一的约束,因为在验证和保存数据时,可能会在插入之前插入具有这些值的另一行。