当我将具有给定用户名的现有用户插入我的数据库时,我正在尝试捕获抛出的异常。正如标题所说,我正在使用EF。当我尝试将用户插入到db时抛出的唯一异常是“UpdateException” - 如何提取此异常以识别它是否是重复的异常或其他什么?
答案 0 :(得分:38)
catch (UpdateException ex)
{
SqlException innerException = ex.InnerException as SqlException;
if (innerException != null && innerException.Number == ??????)
{
// handle exception here..
}
else
{
throw;
}
}
将正确的数字放在与唯一约束违规相对应的??????
处(我不知道这是从头顶开始)。
答案 1 :(得分:14)
因为我在C#中使用EntityFramework,所以我不得不对此做一点改动 - 希望它对任何人有帮助......
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateException ex)
{
SqlException innerException = ex.InnerException.InnerException as SqlException;
if (innerException != null && (innerException.Number == 2627 || innerException.Number == 2601))
{
//your handling stuff
}
else
{
throw;
}
}
我的问题是因为我需要DbUpdateException而不是UpdateException,而我的InnerException对象有一个额外的InnerException对象,其中包含我需要的数字......
答案 2 :(得分:13)
现在在C#6.0中你应该能够做到这样的事情:
catch (UpdateException ex) when ((ex.InnerException as SqlException)?.Number == ??????)
{
// Handle exception here
}
答案 3 :(得分:1)
如果您阻止异常发生,我认为会更好。如果可以使用您的代码,我会执行以下操作:
使用实体框架时,最好的办法是首先尝试使用LINQ的SingleOrDefault获取会给您带来麻烦的条目。现在,您可以使用要插入的实例更新已获取的实体,如果您使用它,则可以使用自动增量保护您的ID号。如果SingleOrDefault为null,您可以安全地添加您的实体。
代码示例:
public override void AddOrUpdate(CustomCaseSearchCriteria entity)
{
var duplicateEntityCheck = GetSingleByUniqueConstraint(entity.UserCode, entity.FilterName);
if (duplicateEntityCheck != null)
{
duplicateEntityCheck.Overwrite(entity);
base.Update(duplicateEntityCheck);
}
else
base.Add(entity);
}
public virtual CustomCaseSearchCriteria GetSingleByUniqueConstraint(string userCode, string filterName)
{
return GetAllInternal().SingleOrDefault(sc => sc.UserCode == userCode && sc.FilterName == filterName);
}
答案 4 :(得分:1)
现在在C#7中,您可以使用is运算符
// 2627 is unique constraint (includes primary key), 2601 is unique index
catch (UpdateException ex) when (ex.InnerException is SqlException sqlException && (sqlException.Number == 2627 || sqlException.Number == 2601))
{
}
答案 5 :(得分:1)
如果您需要在Entity Framework Core中执行相同的操作,则可以使用我构建的库,该库提供强类型异常,包括UniqueConstraintException
:EntityFramework.Exceptions
它允许您捕获如下类型的异常:
using (var demoContext = new DemoContext())
{
demoContext.Products.Add(new Product
{
Name = "a",
Price = 1
});
demoContext.Products.Add(new Product
{
Name = "a",
Price = 10
});
try
{
demoContext.SaveChanges();
}
catch (UniqueConstraintException e)
{
//Handle exception here
}
}
所有您需要做的就是从Nuget安装它,并使用您的OnConfiguring
方法调用它:
class DemoContext : DbContext
{
public DbSet<Product> Products { get; set; }
public DbSet<ProductSale> ProductSale { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseExceptionProcessor();
}
}
答案 6 :(得分:-1)
对于任何数据库类型,您都可以使用反射和相应的错误号(对于MySql 1062):
try
{
var stateEntries = base.SaveChanges();
}
catch (Exception e)
{
if(e is DbUpdateException)
{
var number = (int)e.InnerException.GetType().GetProperty("Number").GetValue(e.InnerException);
if (e.InnerException!= null && (number == 1062))
{
//your handling stuff
}
else
{
messages.Add(e.InnerException.Source, e.InnerException.Message);
}
}
else if (e is NotSupportedException || e is ObjectDisposedException || e is InvalidOperationException)
{
messages.Add(e.InnerException.Source, e.InnerException.Message);
}
}