【问题标题】:how to set string variable as property in subquery如何在子查询中将字符串变量设置为属性
【发布时间】:2021-03-04 16:46:51
【问题描述】:

我有以下物品:

var authors1 = new List<Author>() {
    new Author{ FirstName = "William", LastName = "Smith" },
    new Author{ FirstName = "Fred", LastName = "Jones" }
};

var authors2 = new List<Author>() {
    new Author{ FirstName = "Brian", LastName = "Brains" },
    new Author{ FirstName = "Billy", LastName = "TheKid" }
};

var books = new List<Book>() {
    new Book{ Title = "JAVA", Description = "Description Java", Authors = authors1 },
    new Book{ Title = "PHP", Description = "Description PHP", Authors = authors2 },
};

我想创建一个按作者过滤的子查询。我知道我可以这样做:

IEnumerable<Book> list = books.Where(x => x.Authors.Where(j => j.FirstName == "William").Any());

但我想将 authors 属性用作字符串 var。

var entity = "Authors"
IEnumerable<Book> list = books.Where(x => x[entity].Where(j => j.FirstName == "William").Any());

这不起作用。

【问题讨论】:

  • 为什么不使用 OR 条件。其中(x => x.Authors(...) || x.Title(...) || x.Description(...))
  • 您要解决什么问题?见the XY problem。其他对象/属性是否可以搜索“William”?
  • 这是一个特殊情况。这将是一个通用搜索。这就是我想使用变量的原因。

标签: c# linq iqueryable


【解决方案1】:

我不明白你为什么要这样做......但这里有一种方法可以通过反射达到你想要的:

public bool HasAuthorWithName(Book book, string authName)
{
    // Retrieve list of class' properties
    var p = book.GetType().GetProperties();
        
    // Get list of authors prop by name             
    var entity = "Authors";
    var lstAuthors = p.First(x => x.Name == entity).GetValue(book, null) as List<Author>;
        
    // Filter by author's name
    if (lstAuthors != null && lstAuthors.Any())
    {
        return lstAuthors.Any(j => j.FirstName == authName);
    }
    
    return false;
}

现在你可以调用这个方法了:

IEnumerable<Book> list = books.Where(x => HasAuthorWithName(x, "William"));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-21
    • 2014-09-22
    相关资源
    最近更新 更多