使用表的字符串名称从实体框架动态加载表



假设我有一个字符串列表,表示使用SQL Server中的实体框架生成的类的名称:

public static List<string> tableList = new List<string>
{
"aaa",
"bbb",
"ccc",
"ddd",
"eee",
};

我想从实体加载数据:

DateTime from_date = DateTime.MinValue;
DateTime to_date = DateTime.MaxValue;
using (var ctx = new MyEntities())
{
IList<aaa> aa = ctx.aaa
.Where(a => a.date_added >= from_date && 
a.date_added <= to_date)
.ToList();
}

但我必须在20张或更多的桌子上这样做。

有没有一种方法可以让我动态地做到这一点?类似:

Result res = new Result();
List<Result> r = new List<>();
foreach (string table in tableList)
{
using (var ctx = new MyEntities())
{
IList<*table*> aa = ctx.*table*
.Where(a => a.date_added >= from_date && 
a.date_added <= to_date)
.ToList();
res.quantity = aa.Count();
res.title = table;
}
r.Add(res);
}

所有需要的表都具有列date_added

附言:我只需要计算在一个定义的周期内,每个表中有多少行。如表客户、客户、员工:2020年至2021年有多少人注册。我将输出:

{
"title":"Client",
"quantity": 19,
"from_date": [some_date],
"to_date": [some_date]
},
{
"title":"Customer",
"quantity": 123,
"from_date": [some_date],
"to_date": [some_date]
},
{
"title":"Employee",
"quantity": 31,
"from_date": [some_date],
"to_date": [some_date]
},

考虑到您对我的评论的回答,您可以将类添加到EF生成类的命名空间中。我建议您在这个名称空间中创建一个新的接口,如下所示:

public interface IObjectWithDates
{
DateTime date_added { get; }
}

现在我们希望生成的类有一个date_aded字段来实现IObjectWithDates接口。您可以在同一命名空间中添加一个带有的附加文件,而不是修改生成的类

public partial class Client: IObjectWithDates
{ }
public partial class Customer: IObjectWithDates
{ }
//and so on with the classes you want to track

现在我们有一个程序集,其中包含一些实现IObjectWithDates的类。如果您愿意,可以使用Type t = Type.GetType(...)通过类的名称获取类。您还可以要求C#在您的模型名称空间中为您提供所有实现IObjectWithDates的类:

public IEnumerable<Type> AllTrackedClassesInNameSpace(string namespaceName, Assembly assembly)
{
return assembly.GetTypes()
.Where(x => ((!string.IsNullOrWhiteSpace(x.Namespace)) && (x.Namespace.ToUpper().Contains(namespaceName.ToUpper()))))
.Where(x => x.IsClass)
.Where(x=>typeof(IObjectWithDates).IsAssignableFrom(x));
}

[在此编辑]此时,您将有一个类型列表(以下代码中的IEnumerable<Type> typeList(,所有类型都实现IObjectWithDates,您应该能够做到这一点:

public int MyCount<T>(DbContext ctx) where T: class, IObjectWithDates
{
return ctx.Set<T>().Count(a => a.date_added >= from_date && a.date_added <= to_date);
}

然后

Result res = new Result();
List<Result> r = new List<Result>();
using (var ctx = new DbContext(""))
{
foreach (var type in typeList)
{
var method = this.GetType().GetMethod("MyCount").MakeGenericMethod(type);
res.quantity = (int)method.Invoke(this, new object[]{ ctx });
res.title = table;
}
r.Add(res);
}

一些细节可能需要调整(例如,from_date/to_date可以是MyCount的参数或调用类的属性(,但全局思想是存在的。你可以得到集合<gt;((方法,但在我看来,单独的方法更容易阅读和调试。

注意,生成IList<gt;对象的数量,因为SQL将请求所有对象,EF将在每行实例化许多实例。。。只是用Select Count...计数

最新更新