c# - 选择模型属性包含所有键值对列表的位置

标签 c# linq nhibernate linq-to-nhibernate

我有以下类(class)

public class Account
{
    IEnumerable<AccountData> Data { get; set; }
}

AccountData 在哪里

public class AccountData
{
    public virtual long Id { get; set; }
    public virtual AccountTag AccountTag { get; set; }
    public virtual string Value { get; set; }
}

账户标签在哪里

public class AccountTag
{
    public virtual long Id { get; set; }
    public virtual string Name { get; set; }
}

我想返回数据字段在键值对列表中的所有帐户。 long 是 AccountTag.Id,AccountData.Value 包含字符串

这是我目前所拥有的,但这是在网络服务器上执行的,可能会返回数千个帐户,所以我正在寻找 linq to sql 版本。

public IEnumerable<Account> FindByCompanyDataTags(long companyId, IEnumerable<KeyValuePair<long, string>> tags)
{
    var tempAccounts = (from acc in this.Data where acc.Company.Id == companyId orderby acc.Name select acc);
    IList<Account> accounts = new List<Account>();

    foreach (var account in tempAccounts)
    {
       var matches = true;
       foreach (var t in tags)
       {
          if (account.Data.Any(x => x.AccountTag.Id == t.Key && x.Value.Contains(t.Value)))
          {
            continue;
          }

          matches = false;
          break;
        }

        if (matches)
        {
          accounts.Add(account);
        }
      }

      return accounts;
}

如果我使用 resharper 将其转换为 linq 表达式,我会得到以下结果

public IEnumerable<Account> FindByCompanyDataTags(long companyId, IEnumerable<KeyValuePair<long, string>> tags)
{
  var tempAccounts = (from acc in this.Data where acc.Company.Id == companyId orderby acc.Name select acc);
  IList<Account> accounts = (from account in tempAccounts let matches = tags.All(t => account.Data.Any(x => x.AccountTag.Id == t.Key && x.Value.Contains(t.Value))) where matches select account).ToList();

  return accounts;
}

但是当我运行它时,我得到一个方法不受支持的异常。

这让我很困惑,有什么建议吗?

最佳答案

发生这种情况是因为在第一种情况下,您在此处执行 foreach 期间准备对数据库的查询

foreach (var account in tempAccounts)
{....}

您获得了 Account 对象的集合,并在客户端内存中使用它们(换句话说,您正在使用 Linq to objects)

在第二种情况下,您正在尝试执行 Linq to Sql 查询,但提供程序无法将您的 KeyValuePair 对象转换为 sql 查询,因此它会引发异常。

更新

尝试使用 IQueryable 并通过应用 Where 子句构建查询:

IQueryable<Account> tempAccountsWithWhere = tempAccounts;
foreach (var tag in tags)
{
    tempAccountsWithWhere = tempAccountsWithWhere.Where(
        a => a.Data.Any(
            ad => ad.AccountTag.Id == tag.Key && ad.Value.Contains(tag.Value)));
}
IList<Account> accounts = tempAccountsWithWhere.ToList();

关于c# - 选择模型属性包含所有键值对列表的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8948137/

相关文章:

c# - 提高 linq 查询的性能

c# - 将参数传递给 ViewModel 中的 linq 查询的正确方法

c# - 获取最大行(Linq、NHibernate)

c# - 我应该如何从我的服务层方法中公开总记录数和分页记录的 IEnumerable 集合?

c# - 有利于性能

c# - 如何为接受 xml 文件路径作为参数的方法编写单元测试

sql - Linq to SQL 在一个查询中更新多条记录

nhibernate - 如何将应用程序设置加载到 NHibernate.Cfg.Configuration 对象?

c# - NHibernate3 查询与 QueryOver

c# - bool 属性 Getter 和 Setter 锁定