无法使用 group by 和使用 linq 的多个联接访问字段

Posted

技术标签:

【中文标题】无法使用 group by 和使用 linq 的多个联接访问字段【英文标题】:Not able to access fields with group by and multiple joins with linq 【发布时间】:2016-07-02 07:45:57 【问题描述】:

我只想列出记录中存在差异的平均类别。

这种差异存在于 2 个表中:TestOperation,TestOperationDifference

我想计算以下 3 个字段的平均值:

TestOperation:DiffPerc

If DiffPerc  < 100 
    "Difference is there and take value of DiffPerc to calculate average"
else 
    "Dont take that record"


TestOperationDifference:DiffPerc,DiffRec
If DiffPerc  < 100 
    "Difference is there and take value of DiffPerc and DiffRec to calculate average"
else 
    "Dont take that record"




finalAverage=(
                   Average(TestOperation.DiffPerc) 
                    + Average(TestOperationDifference.DiffPerc)
                    + Average(TestOperationDifference.DiffRec)
              )/3

输出如下:

[0]=Mobile 
    Electronics
    FinalAverage=30.00
[1]=Shoes 
    Sports
    FinalAverage=70.00
.
.
.

我的代码:

public class Category
        
            public int Id  get; set; 
            public string Name  get; set; 
            public Nullable<int> ParentId  get; set; 
            public virtual ICollection<Variants> Variants  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; 
        

        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 decimal DiffPerc  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 decimal DiffPerc  get; set; 
            public decimal DiffRec  get; set; 
            public virtual SubVariants SubVariants  get; set; 
            public virtual SubVariants SubVariants1  get; set; 
            public virtual Test Test  get; set; 
        

我的查询:

 var query = from cat in context.Category
             join v in context.Variants on cat.Id equals v.CategoryId
             join sv in context.SubVariants on v.Id equals sv.VariantId
             join to in context.TestOperation on sv.Id equals to.SourceSubVariantId
join tod in context.TestOperationDifference on sv.Id equals tod.SourceSubVariantId
             where 
              (to.DiffPerc < 100) 
                 ||
              (tod.DiffPerc < 100 )
               group cat by new catid = cat.Id into grp 
              select new 
              
                subcategoryname=grp. //not getting property here                 
                ParentCategoryName=grp.
                FinalAverage=    
              

但是在上面的查询中,当我尝试访问子类别名称时,我 我无法访问它。

Demo Fiddle

【问题讨论】:

为什么要创建一个新的匿名类时要加上括号? @dotctor:好的更新了我的问题 您已将查询分组到grp。你有 grp.Keycatid 属性。您在寻找哪家房产? @dotctor:如果你会看到我的预期输出,你会看到我想要子类别名称和父类别名称,但只有那些在这两个表中有相应记录的子类别(TestOperation,TestOperationDifference)但我需要通过变体和子变体转到此表,因为我在这 2 个表中有子变体 ID 我想你误解了 linq 中group 的概念。如果对您有帮助,您可以通过grp.First() 访问您的分组示例 【参考方案1】:

基本查询应如下所示

 var query = (from cat in category
                         join v in variants on cat.Id equals v.CategoryId
                         join sv in subVariants on v.Id equals sv.VariantId
                         into grp
                         select new  id = cat.Id, subvariant = v.SubVariants, name = cat.Name, type = v.Type)
                         .GroupBy(x => new id = x.id, subvariant = x.subvariant);

您需要将 testOperations 和 testOperationDifferences 应用于查询。

【讨论】:

变体表将包含子类别 ID,而不是父类别 ID 每个连接都必须产生一些输出。您加入类别和变体不会产生任何有效结果。 对不起,我忘了添加类别数据,这就是你没有得到输出的原因。现在检查更新的小提琴【参考方案2】:

这是因为grpIGrouping 的实例,它是集合。正如您可能已经猜到的那样,您需要访问集合的某些元素才能获得CategoryName 属性,或者您可以将Category 的集合按NameId 分组(如果它使在您的情况下有意义),因此您可以使用 grp.Key.Name

访问它

【讨论】:

以上是关于无法使用 group by 和使用 linq 的多个联接访问字段的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 LINQ group by 子句返回唯一的员工行?

Linq to Entity Group By error 无法翻译

C# Linq group by 和 group by into 运用实例

如何将此 GROUP BY / MIN SQL 查询转换为 LINQ?

EF LINQ Group By 和 Sum

将 SQL 查询转换为使用复数和 group by 的 Linq