【问题标题】:How to check whether DbContext.Set<T> exists in model?如何检查模型中是否存在 DbContext.Set<T>?
【发布时间】:2012-05-25 06:08:13
【问题描述】:

我有一种情况,我可能正在使用多个 DbContext,这些 DbContext 可能包含也可能不包含 SomeEntity 的 DbSet。

当然,如果我关闭 SaveChanges 并且该实体不存在,则会出现以下错误:

实体类型 SomeEntity 不是当前模型的一部分 上下文。

如何检查模型中是否存在实体或实体集,如果不存在,则将有问题的代码短路?

理查德

【问题讨论】:

    标签: entity-framework ef-code-first dbcontext


    【解决方案1】:

    当您调用Set&lt;NotMappedEntityType&gt; 时应该立即抛出异常,因此最简单的方法是捕获异常并根据需要进行处理。

    复杂的解决方案要求您浏览映射元数据并搜索必须与 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);
    }
    

    【讨论】:

    • 谢谢。我使用了提供的方法。在我知道有异常的地方使用异常,我总是感到不舒服。如果这有意义的话。
    • 四年后这仍然是真的吗?还是有一些内置的方法来检查这个?
    【解决方案2】:

    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;
            }
        }
    

    【讨论】:

      【解决方案3】:

      这是我的简化答案:

      public partial class MyDbContext : DbContext
      {
         public bool Exists<Tx>() where Tx : class
         {
             var attachedEntity = this.ChangeTracker.Entries<Tx>().FirstOrDefault();
             return (attachedEntity != null);
         }
      }
      

      【讨论】:

        【解决方案4】:

        我经常使用以下实现。

        (我已在上下文类实现的单独接口中声明了此方法。)

        public bool EntitySetExists<T>(T entity) where T : class
        {
            return this.Set<T>().Local.Any(e => e == entity);
        }
        

        如果您看到它抱怨“Any()”扩展方法,只需坚持“使用 System.Linq;”如果丢失。

        【讨论】:

        • 为了澄清我的反对意见,这回答了错误的问题;接受的答案是正确的
        猜你喜欢
        • 1970-01-01
        • 2016-11-30
        • 2019-07-02
        • 2017-12-21
        • 1970-01-01
        • 1970-01-01
        • 2019-09-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多