【问题标题】:How to group by on 2 child entities and get total of both this child entities?如何对 2 个子实体进行分组并获得这两个子实体的总数?
【发布时间】:2016-06-30 10:36:55
【问题描述】:

我想为我的Test Version 0Test Id=100 运行total variables

这是我的表格和记录:

测试:

Id      Version
100        0

变体:

Id      Name       Type   CategoryId
11      Variant1   Diff     2
12      Variant1   Add      2
13      Variant2   Add      3
14      Variant2   Diff     2
15      Variant3   Add      6

子变体

Id     VariantId     Name
66      11           Abc
67      11           PQR
68      11           Xyz

69      12           Abc
70      12           PQR
71      12           Xyz

72      13           Abc
73      13           PQR

74      14           Abc
75      14           PQR
76      14           Xyz

77      15           ABC
78      15           PQR

测试操作

Id   TestId    SourceSubVariantId   TargetSubVariantId   variation
1     100       69                    70                   0
1     100       70                    71                   20
1     100       72                    73                   90

TestOperationDifference:

Id   TestId    SourceSubVariantId   TargetSubVariantId   Unmatch
1     100       66                    67                   0
1     100       67                    68                   2
1     100       74                    75                   7
1     100       75                    76                   0
1     100       77                    78                   26

所以从上面的记录来看,总共有 3 个变体在 2 种操作类型上运行,即 TestOperationTestOperationDifference,以下是特定 Test 100 的 3 个变体:

Variants1(This run in TestOperation)
Variants2(This run in TestOperation)
Variants3(This run in TestOperationDifference)

以上 3 个父变体将出现,因为所有这些父子变体都在 2 个表中使用,即 TestOperation 和 TestOperationDifference。

因此,为了找到总的父变体,我需要从两个表(TestOperation 和 TestOperationDifference)中找出使用了相应的子变体,并基于此我需要 count total parent variants

这是我的课:

public class Test
        {
            public int Id { get; set; }
            public string Version { get; set; }
            public virtual ICollection<TestOperation> TestOperation { get; set; }
            public virtual ICollection<TestOperationDifference> TestOperationDifference { get; set; }
        }

        public class TestOperation
        {
            public int Id { get; set; }
            public Nullable<int> TestId { get; set; }
            public int SourceSubVariantId { get; set; }
            public int TargetSubVariantId { get; set; }
            public int  variation { get; set; }
            public virtual SubVariants SubVariants { get; set; }
            public virtual SubVariants SubVariants1 { get; set; }
            public virtual Test Test { get; set; }

        }

        public class TestOperationDifference
        {
            public int Id { get; set; }
            public Nullable<int> TestId { get; set; }
            public int SourceSubVariantId { get; set; }
            public int TargetSubVariantId { get; set; }

            public int unmatch { get; set; }

            public virtual SubVariants SubVariants { get; set; }
            public virtual SubVariants SubVariants1 { get; set; }
            public virtual Test Test { get; set; }
        }

        public class Variants
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public string Type { get; set; }
            public int CategoryId { get; set; }

            public virtual ICollection<SubVariants> SubVariants { get; set; }

            public virtual Category Category { get; set; }
        }

        public class SubVariants
        {
            public int Id { get; set; }
            public int VariantId { get; set; }
            public string Name { get; set; }

            public virtual Variants Variants { get; set; }
            public virtual ICollection<TestOperationDifference> TestOperationDifference { get; set; }

            public virtual ICollection<TestOperationDifference> TestOperationDifference1 { get; set; }
            public virtual ICollection<TestOperation> TestOperation { get; set; }
            public virtual ICollection<TestOperation> TestOperation1 { get; set; }
        }

我的查询:

var data =(from mk in context.Test
                  select new 
                  {

                      TotalVariants = (mk.TestOperation.Select(t => t.SubVariants).Count()
                                   +
                                      mk.TestOperationDifference.Select(t => t.SubVariants).Count())
                    }).ToList();

输出:8

预期输出:3

【问题讨论】:

  • 你应该真的努力减少问题的大小。您真的需要 5 张桌子来展示您面临的问题吗?您应该简化情况,直到它只是相关部分(但仍然完整)
  • @JonSkeet:实际上我放了这个表是为了便于理解这个问题,如果没有这个表,很难确切知道需要什么输出,但我同意问题的规模很大跨度>
  • 您是说您认为不可能进一步简化这一点吗?你真的需要那么多表和那么多属性吗?这对我来说似乎不太可能。
  • 我添加了一个 Init 方法,使问题更容易验证
  • oops.. 更新仅在同行修订后可见。我在下面的答案中发布了静态方法..

标签: c# asp.net-mvc entity-framework linq


【解决方案1】:

更新

好的学习,这是一个解决方案..

var tot_variants_for_test =
    (from v_name in 
       (from t_op in test 
        select new { v_name = t_op.TestOperation.Select(sv => sv.SubVariants.Variants.Name) }
       ).First().v_name 
     select v_name)
    .Union(
    (from v_name in 
      (from t_opdf in test 
       select new { v_name = t_opdf.TestOperationDifference.Select(sv => sv.SubVariants.Variants.Name) }
     ).First().v_name
     select v_name))
   .Count();

【讨论】:

  • 但是我做了同样的事情并且得到了我在他的问题中提到的错误输出。这两个查询都会给我输出 8 但这不是预期的输出。请查看预期的输出
  • 非常感谢您的回答
【解决方案2】:

从我的脑海中,假设我理解你令人困惑的描述。我认为您需要从TestOperationTestOperationDifference 中提取union 变体,然后区分并计算它们。不确定这是否适用于 EF。

let toQuery = context.Test.SelectMany(mk=>TestOperation.Select(t=>t.SubVariants.Variants));
let todQuery = context.Test.SelectMany(mk=>TestOperationDifference.Select(t=>t.SubVariants.Variants));

let total = toQuery.Concat(todQuery).Disctinct().Count;

另外,您的命名令人困惑。您正在对单项引用使用复数,并且您的模型中有 SourceControlDetailId 不在表格中,并且有 SubVariantsSubVariants1 而不是 SourceSubVariantTargetSubVariant。我建议先解决这个问题。

【讨论】:

  • 非常感谢您的回答,但您能告诉我为什么您使用 selectmany 而不是 select 吗??
  • @Learning 如果你知道它们之间的区别就很明显了。
【解决方案3】:
from test in Tests
where version == 0
let opsVariants = test.TestOperations
  .SelectMany(x => x.SourceSubVariant.Variant).Distinct()
let diffsVariants = test.TestOperationDifferences
  .SelectMany(x => x.SourceSubVariant.Variant).Distinct()
let variants = opsVariants.Union(diffsVariants)
select variants.Count();

【讨论】:

  • 非常感谢您的回答
猜你喜欢
  • 2021-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-30
相关资源
最近更新 更多