动态获取 DbContext 中 Dbset 的行数
Posted
技术标签:
【中文标题】动态获取 DbContext 中 Dbset 的行数【英文标题】:Get Row Count of Dbset in DbContext dynamicly 【发布时间】: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
表。
我想从将DbContext
和Dbset
实例发送给它的函数中获取行数,如下所示:
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();
【问题讨论】:
Could not find an implementation of the query pattern的可能重复 看看这个方法的预期用途会很有趣,即GetRowCount(context, ???)
@IvanStoev:???
Ivan 是什么?你的意思是传递一个参数给函数?
否 :) 问题是如何获得 DbSet
以便将其传递给方法。只是想知道为什么你需要那个方法,因为例如context.Logs.Count()
很容易做到这一点。
嗯,我不确定。现在我看到了您的更新,并且以某种方式可以解决Count
问题,但请注意非通用DbSet
几乎无法使用。您不能针对它编写普通的 LINQ,ToList
等也不能。如果您绝对确定问题只是 Count()
,我想我们可以提供帮助。
【参考方案1】:
DbSet
不实现 IQueryable,DbSet<T>
实现。例如
public static int GetRowCount<T>(DbContext DatabaseContext, DbSet<T> TableEntity)
var countVal = TableEntity.Count();
return countVal;
【讨论】:
它会生成此错误:类型“T”必须是引用类型才能将其用作泛型类型或方法“DbSetDbcontex
中的表格执行一些操作...例如表格行数...或过滤某些行并将其显示给最终用户...因此,我发送了一个 dbcontext
和 dbset
的实例,女巫必须从中计算或过滤【参考方案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;
这个类添加一个通用方法AsEnumerable
到DbSet
实例,当你想使用它时,例如Count:
var count = (from a in TableEntity.AsEnumerable() select a).Count();
【讨论】:
这是个坏主意,因为它会导致 DbSet 中的所有实体都加载到内存中,而不是在 DB 中运行计数。 这特别慢。以上是关于动态获取 DbContext 中 Dbset 的行数的主要内容,如果未能解决你的问题,请参考以下文章
.Net使用配置文件 DbContext 动态加载 DbSet
我可以克隆一个 IQueryable 以在另一个 DbContext 的 DbSet 上运行吗?
EF dbcontext 在 dynamo 自定义节点中返回一个空的 dbset