我有一个表在两列上有唯一索引, F1 和 Kant [1]。只有主键(这是一个整数Id)和这个索引没有外键。
在添加新记录之前,我会检查数据库中是否存在具有此索引的记录。[2] 我知道它没有! ExistsLaserData 返回false。
然后我将记录添加到 DbSet 并执行 SaveChanges 但现在我得到了一个异常
DbUpdateException:SqlException:违反UNIQUE KEY约束 'IX_laserdata_F1_Kant'。无法在对象中插入重复键 'dbo.LaserData'。重复键值为(123456,NULL)。
这是我添加的记录!
使用
初始化上下文LaserDataContext context = new LaserDataContext();
OrderBy(x => x.F1).ThenBy(x => x.Kant).ToList();
我正在使用的两种方法
public bool ExistsLaserData(string article, string kant)
{
bool result = false;
var found = _context.LaserData.Where(x => x.F1 == article && x.Kant == kant).FirstOrDefault();
if (found != null)
{
result = true;
}
return result;
}
public void AddLaserData(ref LaserData d)
{
try
{
_context.LaserData.Add(d);
_context.SaveChanges();
}
catch (Exception ex)
{
throw;
}
}
当我检查记录时为什么记录不存在?或者当我执行SaveChanges时为什么记录存在?
[1]这个数据库的开头是一个Excel文档,因此名字很奇怪......
[2]我不想跳过ExistLaserData检查,所以请不要建议我只使用例外。
答案 0 :(得分:0)
我认为您应该将文章转换为整数,然后检查是否存在。
正如你所说F1是int而article是字符串所以你无法比较它们。
然后您可以使用它来添加或更新:
LaserData found = _context.LaserData.FirstOrDefault( p => p.F1==(int) article);
if(found == null)
{
_context.LaserData.Add(d);
_context.SaveChanges();
}
我希望这会对你有所帮助。也许你需要解释更多,如果这不是你想要的。
如果文章类型与F1类似,那么你可以在没有强制转换的情况下写入int:
LaserData found = _context.LaserData.FirstOrDefault( p => p.F1== article);
如果它不是唯一的,你不必检查kant。但你可以检查一下你是否喜欢。
编辑: 用这个:
public bool ExistsLaserData(string article, string kant)
{
bool result = false;
LaserData found = _context.LaserData.FirstOrDefault(x => x.F1 == article && x.Kant == kant);
if (found != null)
{
result = true;
}
return result;
}
答案 1 :(得分:0)
在这里,您要检查同一行中的两个值,并且仅当两个键对于单个行都相同时才返回一行。
你能试试吗?而不是&& ,使用||
public bool ExistsLaserData(string article, string kant)
{
bool result = false;
var found = _context.LaserData.Where(x => x.F1 == article || x.Kant == kant).FirstOrDefault();
if (found != null)
{
result = true;
}
return result;
}
答案 2 :(得分:0)
很可能您的kant
属性未正确映射。这将解释异常和代码的行为。
null
插入kant
值,这是有意义的,因为EF由于映射不正确而从未发送过值。ExistsLaserData
传递给false
参数的方法,null
始终会返回kant
。这会导致您的代码始终尝试使用AddLaserData
方法。因此,修复方法是确保正确映射此属性并更正列。
如果不是,那么您尝试插入多个具有相同F1
值但具有null
kant
值的记录,这将破坏唯一索引。唯一的方法是使用where
过滤器更改索引,以便仅检查kant
何时有值。
CREATE UNIQUE NONCLUSTERED INDEX [IX_laserdata_F1_Kant] ON dbo.LaserData (F1 ASC, Kant ASC) WHERE (Kant IS NOT NULL)
答案 3 :(得分:0)
好的,我找到了错误发生的地方,它与ExistsLaserData无关。 ExistsLaserData工作正常!
因为这是一个全新的问题,所以我会提出一个新问题
感谢您提出的所有建议,我将使用其中一些建议!
PS!作为预告片。在SaveChanges事件的重写中,我Trim()所有字符串都是字符串。这会使base.SaveChanges抛出异常......