按名称访问DbSet的属性

9

我有一个 DbSet<T>

我想通过名称访问它的一个属性。

这个可能吗?

我基本上正在创建一个通用函数,所以对于任何我拥有的DbSet,我可以指定一个列并列出该列的值。

您可以通过执行context.Set(T)从上下文中获取DbSet本身,但我不确定字段。


这里的通用上下文是什么?您能展示一下您想让查询起源的方法的签名(以查看我们有哪种通用类型参数)以及使用该方法的一行语句和预期结果吗? - Simon Belanger
概念是我有一张名为“books”的表,其中一个字段是“author”,我想在“author”列上执行搜索。我还有很多其他表格,我想在这些表格上执行相同的搜索,因此我要创建一个通用方法,在该方法中,我可以通过匹配列“Author”或任何我指定的列来获取匹配对象,例如IEnumerable<T> - NibblyPig
2个回答

15

我之前用反射做过类似的事情。

T item = context.Set(T).First();
string propName = "MyProperty";
object value = item.GetType().GetProperty(propName).GetValue(item, null);

当然,请注意,您需要手动将值转换为特定类型,或使用ToString,这在所有基本类型上都可以很好地工作。

这假定您已经从服务器获取了数据,现在需要处理它。

编辑:

如果您想创建查询,则可以使用this找到所需内容!

显然,您要查找的内容现在作为Entity Framework的一部分提供。

有一个可用的扩展方法,允许您使用.Select("propertyName")返回IQueriable。请记得将System.Linq.Dynamic添加到您的using部分。

然后,您可以通过指定参数名称来创建选择查询。

List<object> data = (db.Set<SetType>()
                       .Where("propertyName == @0 && someOtherProperty == @1", propertyValue, someOtherPropertyValue)
                       .Select("propertyName") as IEnumerable<object>).ToList();

很酷,我刚试了一下,你觉得性能会有什么影响吗?我认为它只会生成一条SQL语句,所以如果我想选择所有具有“Name”字段为“Hello”的实体,那么我可以只需进行dbSet.Where(c => c.GetType ..... GetValue ... == "Hello"),而性能问题将是微不足道的? - NibblyPig
1
@SLC 我找到了解决你问题的方法 - 请查看更新后的答案! :) - MBender
好的,我已经尝试了第一部分,看起来应该可以工作,但是LINQ to Entities尝试翻译整个GetType GetProperty的内容并失败了。我想这是因为那部分需要在服务器端完成,只有结果才能进入LINQ to entities?dbSet.Where(c => c.GetType().GetProperty(propertyName).GetValue(c, null) == someString) - NibblyPig
@SLC 就像我之前说的那样,我已经编辑了答案 - 检查第二部分! :) - MBender
请查看提供的示例代码,其中包含一个Where子句。我还编辑了我的回答,以包含一个示例Where。如果你仍然有问题,那么你需要更具体地说明。 - MBender
显示剩余4条评论

6

请查看关于动态LINQ的这篇文章

使用提供的代码,我能够编写一个LINQ到实体的查询,如下所示:

var query = context.Set(Type.GetType("Person")).Select("Name");

在 .Net Core 中 context.Set() 不可用吗? - RHarris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接