【问题标题】:Get Row Count of Dbset in DbContext dynamicly动态获取 DbContext 中 Dbset 的行数
【发布时间】:2017-12-10 14:09:01
【问题描述】:

我有一个表单,它将我的DbContext 的实例和表的实体传递给它,如下所示:

public frm_foo(DbContext DatabaseContext, DbSet TableEntity)
        {
           InitializeComponent();
           var res =GetRowCount(DatabaseContext,TableEntity);
        }

并通过以下方式致电表单承包商:

new frm_foo(dbContext, dbContext.Set<IpRoom>()).ShowDialog();

上下文包含一个IpRoom 表。

我想从将DbContextDbset 实例发送给它的函数中获取行数,如下所示:

public int GetRowCount(DbContext DatabaseContext, DbSet TableEntity)
   {
       var countVal = (from a in DatabaseContext.Set(TableEntity.GetType())
                        select a).Count();
       return countVal;
   }

但出现错误:

找不到源类型的查询模式的实现 '数据库集'。未找到“选择”。

DatabaseContext.Set(TableEntity.GetType()) 返回一个数据库集!有人知道我怎么了?提前致谢

Ps:我不想使用SqlQuery,类似:

var sql = "SELECT COUNT(*) FROM dbo.IpRoom";
var total = context.Database.SqlQuery<int>(sql).Single();

【问题讨论】:

  • 看看这个方法的预期用途会很有趣,即GetRowCount(context, ???)
  • @IvanStoev:???Ivan 是什么?你的意思是传递一个参数给函数?
  • 否 :) 问题是如何获得 DbSet 以便将其传递给方法。只是想知道为什么你需要那个方法,因为例如context.Logs.Count() 很容易做到这一点。
  • 嗯,我不确定。现在我看到了您的更新,并且以某种方式可以解决Count 问题,但请注意非通用DbSet 几乎无法使用。您不能针对它编写普通的 LINQ,ToList 等也不能。如果您绝对确定问题只是 Count(),我想我们可以提供帮助。

标签: c# entity-framework dbcontext dbset


【解决方案1】:

DbSet 不实现 IQueryable,DbSet&lt;T&gt; 实现。例如

public static int GetRowCount<T>(DbContext DatabaseContext, DbSet<T> TableEntity)
{
    var countVal = TableEntity.Count();
    return countVal;
}

【讨论】:

  • 它会生成此错误:类型“T”必须是引用类型才能将其用作泛型类型或方法“DbSet”中的参数“TEntity”
  • 对。 T 应该是在您的 DbContext 子类中定义的实体类型。也许您应该更详细地解释您要完成的工作。
  • 我解释了更多问题大卫。你能看一下吗?
  • 再次阅读问题。仍然不知道你想做什么。也许简短而完整的复制会有所帮助。
  • 事实上我是在表格中对Dbcontex 中的表格执行一些操作...例如表格行数...或过滤某些行并将其显示给最终用户...因此,我发送了一个 dbcontextdbset 的实例,女巫必须从中计算或过滤
【解决方案2】:

我使用类似这样的函数来了解表格是否没有元素并且需要用数据播种才能使用:

using System;
using System.Linq;

namespace EFCoreTutorial
{
    class Program
    {
        static void Main(string[] args)
        {    
            using (var context = new Data.SchoolContext())
            {
                var studentsCount = context.Students.Count();

                if (studentsCount == 0)
                {
                    // Seed all your starting data now
                    var student = new Model.Student()
                    {
                        Name = "Ali",
                    };

                    context.Students.Add(student);
                    context.SaveChanges();
                }
            }
        }
    }
}

SchoolContext 派生自 DbContext。

【讨论】:

    【解决方案3】:

    要获得通用行数,我使用以下方法。

    public static int GetRowCount<T>(DbContext context)
        {
            // Get the generic type definition
            var method = typeof(DbContext).GetMethod(
                nameof(DbContext.Set), BindingFlags.Public | BindingFlags.Instance);
    
            // Build a method with the specific type argument you're interested in
            method = method.MakeGenericMethod(typeof(T));
    
            var iEnumerable = method.Invoke(context, null) as IQueryable<T>;
    
            return (iEnumerable ?? throw new InvalidOperationException()).Count();
        }
    

    【讨论】:

      【解决方案4】:

      为您的项目添加一个类作为打击:

      namespace System.Data.Entity
      {
        public static class EntityFrameworkExtensions
        {
          public static IEnumerable<object> AsEnumerable(this DbSet set)
          {
            foreach (var entity in set)
              yield return entity;
          }
        }
      }
      

      这个类添加一个通用方法AsEnumerableDbSet 实例,当你想使用它时,例如Count

       var count = (from a in TableEntity.AsEnumerable() select a).Count();
      

      【讨论】:

      • 这是个坏主意,因为它会导致 DbSet 中的所有实体都加载到内存中,而不是在 DB 中运行计数。
      • 这特别慢。
      猜你喜欢
      • 2012-11-11
      • 2013-07-16
      • 2016-02-29
      • 1970-01-01
      • 1970-01-01
      • 2016-05-13
      • 2021-05-12
      • 2020-12-19
      • 1970-01-01
      相关资源
      最近更新 更多