通过 LINQ 进行多连接和分组

Posted

技术标签:

【中文标题】通过 LINQ 进行多连接和分组【英文标题】:Multiple Join and Group By LINQ 【发布时间】:2013-01-29 00:23:12 【问题描述】:

我需要生成这个数据模型(示例):

IList<FeatureGroupFeaturesDto> fcf = new List<FeatureGroupFeaturesDto>();

fcf.Add(new FeatureGroupFeaturesDto

    FeatureGroup = new FeatureGroupDto  Id = 1, Name = "Interior" ,
    Features = new List<FeatureDto>  
        new FeatureDto  Id = 7, Name = "Bancos Traseiros Rebatíveis" ,
        new FeatureDto  Id = 35, Name = "Computador de Bordo" ,
        new FeatureDto  Id = 38, Name = "Suporte para Telemóvel" 
    ,
);

fcf.Add(new FeatureGroupFeaturesDto

    FeatureGroup = new FeatureGroupDto  Id = 2, Name = "Exterior" ,
    Features = new List<FeatureDto>  
        new FeatureDto  Id = 13, Name = "Barras de Tejadilho" ,
        new FeatureDto  Id = 15, Name = "Retrovisores Aquecidos" ,
        new FeatureDto  Id = 16, Name = "Retrovisores Elétricos" 
    ,
);

基于实体:

public class Category

    public int Id  get; set; 
    public string Name  get; set; 


public class CategoryFeatureGroupFeature

    [Key]
    [Column("Category_Id", Order = 0)]
    public int Category_Id  get; set; 

    [Key]
    [Column("FeatureGroup_Id", Order = 1)]
    public int FeatureGroup_Id  get; set; 

    [Key]
    [Column("Feature_Id", Order = 2)]
    public int Feature_Id  get; set; 


public class Feature

    public int Id  get; set; 
    public string Name  get; set; 


public class FeatureGroup

    public int Id  get; set; 
    public string Name  get; set; 

基本上,这个想法是获取按 FeatureGroup 分组的类别的所有特征。

编辑:

我正在尝试将信息放入此模型中:

public class FeatureCategoryFeatures

    public FeatureGroup FeatureGroup  get; set; 
    public IList<Feature> Features  get; set; 

如何使用 LINQ 和实体框架实现这一目标?

谢谢。

【问题讨论】:

你的 linq 查询现在是什么样子的? 嗨,像这样,但我得到了一些基础部分:var featuresDomain = (from cfg in categoryFeatureGroupFeaturesQuery where cfg.Category_Id == categoryId join fg in featureGroupQuery on cfg.FeatureGroup_Id 等于 fg.Id join f in featureQuery on cfg.Feature_Id 等于 f.Id group fg by fg.Name into groupedFeatures group f by f.Id into grp select f); ***.com/a/9276585/1620568 没有Group By子句 教人钓鱼... 【参考方案1】:

可能这会起作用-我没有检查过。

虽然代码很糟糕:

List<CategoryFeatureGroupFeature> cfcgQ = new List<CategoryFeatureGroupFeature>();
        List<Category> cat = new List<Category>();
        List<Feature> fe = new List<Feature>();
        List<FeatureGroup> feag = new List<FeatureGroup>();

        var query = (from p in cfcgQ
                     join q in feag on p.FeatureGroup_Id equals q.Id
                     join r in fe on p.Feature_Id equals r.Id
                     where p.Category_Id == 1
                     select new  q.Name, q.Id, FeatureName = r.Name ).GroupBy(p => new  p.Name, p.FeatureName, p.Id ).ToList().OrderBy(p => p.Key.FeatureName).ThenBy(p => p.Key.Name);

【讨论】:

您好,它返回了一个包含 N 个 FeatureGroups 的列表,每个组中只有一个特征,其中 N 是总特征数。是否可以返回包含所有功能的组列表?谢谢【参考方案2】:

我修改了答案,假设类别可以有多个组(希望我的假设是正确的)。我使用匿名对象作为返回结果,但意图应该很清楚。

/*** DATA ***/
IList<Feature> featuresList = new List<Feature>  
        new Feature  Id = 13, Name = "Barras de Tejadilho" ,
        new Feature  Id = 15, Name = "Retrovisores Aquecidos" ,
        new Feature  Id = 16, Name = "Retrovisores Elétricos" ,
        new Feature  Id = 7, Name = "Bancos Traseiros Rebatíveis" ,
        new Feature  Id = 35, Name = "Computador de Bordo" ,
        new Feature  Id = 38, Name = "Suporte para Telemóvel" ,
        new Feature  Id = 1, Name = "2nd Exterior Feature" 
;
IList<FeatureGroup> featureGroupList = new List<FeatureGroup>
    new FeatureGroup  Id = 1, Name = "Interior" ,
    new FeatureGroup  Id = 2, Name = "Exterior" ,
    new FeatureGroup  Id = 3, Name = "2nd Exterior" 
;
IList<Category> categoryList = new List<Category>
    new Category Id=1, Name="All interior" ,
    new Category  Id=2, Name="All exterior" 
;
IList<CategoryFeatureGroupFeature> cfcList = new List<CategoryFeatureGroupFeature>

    new CategoryFeatureGroupFeature  Category_Id = 1, FeatureGroup_Id = 1, Feature_Id = 7 ,
    new CategoryFeatureGroupFeature  Category_Id = 1, FeatureGroup_Id = 1, Feature_Id = 35 ,
    new CategoryFeatureGroupFeature  Category_Id = 1, FeatureGroup_Id = 1, Feature_Id = 38 ,
    new CategoryFeatureGroupFeature  Category_Id = 2, FeatureGroup_Id = 2, Feature_Id = 13 ,
    new CategoryFeatureGroupFeature  Category_Id = 2, FeatureGroup_Id = 2, Feature_Id = 15 ,
    new CategoryFeatureGroupFeature  Category_Id = 2, FeatureGroup_Id = 2, Feature_Id = 16 ,
    new CategoryFeatureGroupFeature  Category_Id = 2, FeatureGroup_Id = 3, Feature_Id = 1 
;

/*** QUERY ***/
var result = from c in categoryList
                select new 
                    Id = c.Id,
                    Name = c.Name,
                    FeatureGroups = from fg in featureGroupList
                                    where (from cfc in cfcList
                                        where cfc.Category_Id == c.Id
                                        select cfc.FeatureGroup_Id).Distinct()
                                    .Contains(fg.Id)
                                    select new 
                                        Id = fg.Id,
                                        Name = fg.Name,
                                        Features = (from f in featuresList
                                                join cfc2 in cfcList on f.Id equals cfc2.Feature_Id
                                                where cfc2.FeatureGroup_Id == fg.Id
                                                select f).Distinct()
                                    
                ;

您可以使用joingroup by 的组合获得相同的结果,但我选择了Distinct()

【讨论】:

您好,谢谢!令人惊讶的是你是如何做到这一点的 :) 我正在尝试将你的结果放入我的 IList 但它不起作用,你能帮我解决这个问题吗?再次非常感谢您。

以上是关于通过 LINQ 进行多连接和分组的主要内容,如果未能解决你的问题,请参考以下文章

通过 linq 对实体查询进行分组,以通过加入表来获取具有最新时间戳的一条记录

如何通过 LINQ to Sql 结果上的数据对分组进行 lambda?

如何对C#类对象值进行分组。 LINQ可以吗?

Linq使用多字段分组、排序

LINQ技巧:如何通过多次调用GroupBy实现分组嵌套

如何通过 LINQ 扩展获取 group 的分组值列表