【问题标题】:Linq inner join using Split使用拆分的 Linq 内连接
【发布时间】:2014-07-03 08:51:44
【问题描述】:

实际上,我正在使用2 tables,例如GREETING_TRANSACTIONSCOUNTRIES

COUNTRIES 表中,我维护CountryShortCodeCountryFullName 的列表。

在发送Greetings 时,我将CountryCodes, 的方式保存在GREETING_TRANSACTIONS 中。例如:IN,MY,CN 用于印度、马来西亚和中国。

现在我正在做的是:首先我使用此查询获取GREETING_TRANSACTIONS 的列表

var Messages =
(
    from u in obj.GREETING_TRANSACTIONS
    orderby u.SENT_DATE descending
    select new
    {
        u.ID,
        u.COUNTRIES,
        u.TITLE,
        u.MESSAGE,
        u.SENT_DATE,
        u.GREETING_TYPE,
        u.CATEGORY_NAME
    }
).ToList();

然后获取每个项目和splitting COUNTRIES 列并使用CountryShortCode 获取相关的CountryFullName 并准备DataTable 并绑定到GridView

是否可以使用联接在单个查询中完成所有操作?

可能是这样的:

var Messages1 =
(
    from u in obj.GREETING_TRANSACTIONS
    join c in obj.COUNTRY_MASTER
            on u.COUNTRIES.Split(',') equals c.COUNTRY_SHORTNAME
    orderby u.SENT_DATE descending
    select new
    {
        u.ID,
        u.COUNTRIES,
        u.TITLE,
        u.MESSAGE,
        u.SENT_DATE,
        u.GREETING_TYPE,
        u.CATEGORY_NAME,
        c.COUNTRY_FULLNAME
    }
).ToList();

我是 Linq 的新手,发现这非常困难。

是否可以通过使用逗号分隔的 ShortCodes 并生成 Fullnames 来查询数据?

我需要使用子查询吗?

【问题讨论】:

  • 是的,你可以这样做
  • 你到底想要什么?
  • 是的。但是要循环所有国家/地区,需要很长时间,例如 45 秒。是否可以使用 Joins 编写单个查询?
  • 在数据库中使用逗号分隔的字段通常是一个设计缺陷。您应该有一个问候语和国家/地区之间的关系表,因为它是多对多关系。
  • 正如@RaphaëlAlthaus 提到的,如果您将拥有 M2M,那么您可以使用 LINQ 进行查询而不使用连接

标签: c# asp.net .net linq join


【解决方案1】:

您遇到的问题是您无法对拆分进行连接查询。您需要从中创建一个SelectMany

因此,鉴于国家/地区列表非常小,那么简单的方法就是创建一个查找。

保留您的Messages 查询,然后执行以下操作:

var lookup = obj.COUNTRY_MASTER
    .ToDictionary(x => x.COUNTRY_SHORTNAME, x => x.COUNTRY_FULLNAME);

var Messages1 =
(
    from m in Messages
    from c in m.COUNTRIES.Split(',')
    where lookup.ContainsKey(c)
    orderby m.SENT_DATE descending
    select new
    {
        m.ID,
        m.COUNTRIES,
        m.TITLE,
        m.MESSAGE,
        m.SENT_DATE,
        m.GREETING_TYPE,
        m.CATEGORY_NAME,
        COUNTRY_FULLNAME = lookup[c],
    }
).ToList();

根据下面的评论:

var Messages1 =
(
    from m in Messages
    orderby m.SENT_DATE descending
    select new
    {
        m.ID,
        m.COUNTRIES,
        m.TITLE,
        m.MESSAGE,
        m.SENT_DATE,
        m.GREETING_TYPE,
        m.CATEGORY_NAME,
        COUNTRY_FULLNAME = String.Join(
            ", ",
            m.COUNTRIES
                .Split(',')
                .Where(x => lookup.ContainsKey(x))
                .Select(x => lookup[x])),
    }
).ToList();

【讨论】:

  • 这不太可能奏效,因为 OP 可能使用 Linq2SQL Linq2EF 或 Linq2nH,因为他们使用了术语“表”。
  • @Aron - 不,它工作得很好。 OP 在他的第一个查询中有一个.ToList().ToDictionary() 也会将查找带入内存。我一直用这个。
  • 啊...公平竞争...但现在的问题是您在内存中进行所有过滤并且没有索引。 PS您可能希望将字符串比较器传递给ToDictionary
  • @RealSteel - 通过将数据放入内存然后对其进行查询而不是尝试在单个复杂查询中获取数据,您会感到惊讶。
  • @RealSteel - 调用.ToList().ToArray().ToDictionary(...).ToLookup(...) 强制查询运行并将数据带入内存。否则 linq 调用将延迟到实际使用时,而不是在定义时。
【解决方案2】:

使用逗号分隔的列表作为数据字段不是一个好主意。您需要一个额外的多对多表链接 GREETING_TRANSACTIONSCOUNTRIES

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-23
    • 1970-01-01
    • 2012-10-17
    • 2010-10-06
    相关资源
    最近更新 更多