实体框架按日期获得每个组合中的一个

时间:2016-03-14 15:11:18

标签: c# asp.net entity-framework

我在ASP.NET中使用Entity Framework。我有像这样的桌子:

+----+--------------------------+-------+-------+------------+
| id |         content          | type1 | type2 |    date    |
+----+--------------------------+-------+-------+------------+
|  0 | Some text                | TypeA | TypeB | 2013-04-01 |
|  1 | Some older text          | TypeB | TypeA | 2012-03-01 |
|  2 | Some even older texttext | TypeB | TypeC | 2011-01-01 |
|  3 | A dog                    | TypeC | TypeB | 2013-04-01 |
|  4 | And older dog            | TypeC | TypeB | 2012-03-01 |
|  5 | An even older dog        | TypeA | TypeC | 2011-01-01 |
|  6 | More text                | TypeA | TypeB | 2013-03-01 |
+----+--------------------------+-------+-------+------------+

我已经可以获得最近出现的类型1或类型2,但我想查询数据库以获取最近出现的两种类型的组合:

+----+--------------------------+-------+-------+------------+
| id |         content          | type1 | type2 |    date    |
+----+--------------------------+-------+-------+------------+
|  0 | Some text                | TypeA | TypeB | 2013-04-01 |
|  3 | A dog                    | TypeC | TypeB | 2013-04-01 |
|  5 | An even older dog        | TypeA | TypeC | 2011-01-01 |
+----+--------------------------+-------+-------+------------+

谢谢!

编辑:列类型1或类型2基本相同,因此如果Type1 = A且Type2 = B,则它与Type1 = B和Type2 = A相同。

1 个答案:

答案 0 :(得分:0)

这可以解决问题,除了一个小问题,我将在代码示例后描述。

var grouped = datacontext.Table
    .GroupBy(
        item => new { item.Type1, item.Type2 },
        (key, groupData) => groupData.OrderBy(x => x.TheDate).First())
    .ToArray();

问题在于,这种分组是在Type1和Type2的组合上完成的,按顺序。所以你在评论中说的是Type1=A AND Type2=B等于Type1=B AND Type2=A是一个问题。

我真的不知道EF(或L2S)是否可以编译它,但值得一试。

var grouped = datacontext.Table
    .Select(x => new Data // TODO: Update to the correct typename
    {
        x.Id,
        x.Content,
        Type1 = x.Type1.CompareTo(x.Type2) > 0 ? x.Type2 : x.Type1,
        Type2 = x.Type1.CompareTo(x.Type2) > 0 ? x.Type1 : x.Type2,
        x.TheDate
    })
    .GroupBy(
        item => new { item.Type1, item.Type2 },
        (key, groupData) => groupData.OrderBy(x => x.TheDate).First())
    .ToArray();

如果上面没有编译,那么另一个选择是在数据库分组后纠正Type1 / Type2值,并在内存中再次执行分组。是的,这意味着它将分组两次(一次由数据库组成,一次在内存中),但它可以工作,并且不需要将整个表导入内存。

var grouped = datacontext.Table
    .GroupBy(
        item => new { item.Type1, item.Type2 },
        (key, groupData) => groupData.OrderBy(x => x.TheDate).First())
    .AsEnumerable()
    .GroupBy(
        item => new {
            // Group by the possible-swapped-values of Type1 and Type2
            Type1 = x.Type1.CompareTo(x.Type2) > 0 ? x.Type2 : x.Type1
            Type2 = x.Type1.CompareTo(x.Type2) > 0 ? x.Type1 : x.Type2
        },
        (key, groupData) => groupData.OrderBy(x => x.TheDate).First())
    .ToArray();

我认为我最喜欢最后一个选项,因为:

  • 它可以被翻译成sql(没有像string.CompareTo
  • 这样的特殊功能
  • 最多只会是数据库产生的记录数量的两倍,而不再是(我认为在不知道我们正在谈论的总数据量的情况下可以接受)