选择模型属性包含键值对列表中所有内容的位置

发布于 2024-12-28 01:45:41 字数 2037 浏览 2 评论 0原文

我有以下类

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; }
}

和 Account Tag 为

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

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

Here 是我到目前为止所拥有的,但这是在 Web 服务器上执行的,可能会返回数千个帐户,因此我正在寻找 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;
}

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

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

I have the following class

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

where AccountData is

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

and where Account Tag is

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

I want to return all accounts where the Data field is in a list of key value pairs . long is the AccountTag.Id, and the AccountData.Value contains the string

Here is what I have so far, but this is performed on the web server and there could be thousands of accounts returned so I am looking for a linq to sql version.

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;
}

If I use resharper to convert this into a linq expression I get the following

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;
}

But when I run this I get a method not supported exception.

This is really confusing me, any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浅听莫相离 2025-01-04 01:45:41

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

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

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

在第二种情况下,您尝试执行 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();

That's happening because in first case you prepare query to db during foreach execution here

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

You get collection of Account objects and working with them on client side in memory (other words, you're using Linq to objects)

In the second case you're trying execute Linq to Sql query but provider cannot translate working with your KeyValuePair objects into sql query, therefore it raise exception said about that.

UPDATE

Try to use IQueryable and build your query thorugh consequently applying Where clause:

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();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文