我有一种情况,我可能正在使用多个 DbContext,这些 DbContext 可能包含也可能不包含 SomeEntity 的 DbSet。
自然,如果我触发 SaveChanges 并且该实体不存在,则会发生以下错误:
实体类型 SomeEntity 不是当前上下文模型的一部分。
如何检查模型中是否存在实体或实体集,如果不存在则将有问题的代码短路?
理查德
我有一种情况,我可能正在使用多个 DbContext,这些 DbContext 可能包含也可能不包含 SomeEntity 的 DbSet。
自然,如果我触发 SaveChanges 并且该实体不存在,则会发生以下错误:
实体类型 SomeEntity 不是当前上下文模型的一部分。
如何检查模型中是否存在实体或实体集,如果不存在则将有问题的代码短路?
理查德
调用时应立即抛出异常,Set<NotMappedEntityType>
因此最简单的方法是捕获异常并根据需要进行处理。
复杂的解决方案要求您浏览映射元数据并搜索必须与 CLR 类型同名的映射实体类型。您可以在派生的上下文类中添加此方法来检查实体类型的存在:
public bool Exists<TEntity>() where TEntity : class
{
string entityName = typeof(TEntity).Name;
ObjectContext objContext = ((IObjectContextAdapter)this).ObjectContext;
MetadataWorkspace workspace = objContext.MetadataWorkspace;
return workspace.GetItems<EntityType>(DataSpace.CSpace).Any(e => e.Name == entityName);
}
EF Core 2.x 更新扩展方法:如果不存在则返回 NotFound,如果模型上定义了实体 TEntity,则返回 DbSetType 或 ViewType。
public enum QueryType
{
DbsetType,
ViewType,
NotFound
}
public static class DbContextExtensions
{
public static QueryType GetQueryType<TEntity>(this DbContext context) where TEntity : class
{
var metaData = context.Model.FindEntityType(typeof(TEntity));
if (metaData == null)
return QueryType.NotFound;
return metaData.IsQueryType ? QueryType.ViewType : QueryType.DbsetType;
}
}
这是我的简化答案:
public partial class MyDbContext : DbContext
{
public bool Exists<Tx>() where Tx : class
{
var attachedEntity = this.ChangeTracker.Entries<Tx>().FirstOrDefault();
return (attachedEntity != null);
}
}
我经常使用以下实现。
(我已在上下文类实现的单独接口中声明了此方法。)
public bool EntitySetExists<T>(T entity) where T : class
{
return this.Set<T>().Local.Any(e => e == entity);
}
如果在这种情况下您看到它抱怨“Any()”扩展方法,只需坚持“使用 System.Linq;” 如果丢失。