加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 使用LINQ的复杂GROUP BY

发布时间:2020-12-16 01:56:51 所属栏目:百科 来源:网络整理
导读:我熟悉LINQ中的简单GROUP BY操作.但我有一个复杂的情况.我需要使用group by将CostPageRow记录转换为CostPageSelection域对象.我们如何从列表中获取域对象? 注意:我在上面写的组没有给出List.我不知道怎么写. CostPageSelection里面有一个列表. ListCostPag
我熟悉LINQ中的简单GROUP BY操作.但我有一个复杂的情况.我需要使用group by将CostPageRow记录转换为CostPageSelection域对象.我们如何从列表中获取域对象?

注意:我在上面写的组没有给出List.我不知道怎么写. CostPageSelection里面有一个列表.

List<CostPageRow> costPageRows = searchDAL
    .GetAllCostPages(contextObject,searchCriteria);


var orderGroups = costPageRows
     .GroupBy(x => new { 
         x.CostPage,x.Description,x.BillTypeDirect,x.BillTypeWarehouse,x.OrderType,x.Vendor,x.VendorID 
     })
     .Select(y => new CostPageParent { 
           CostPage = y.First().CostPage 
     })
     .ToList();

存储过程的结果

public class CostPageRow
{
    //CostPage Parent

    public string CostPage { get; set; }
    public string Description { get; set; }
    public string Vendor { get; set; }
    public string VendorID { get; set; }
    public string BillTypeDirect { get; set; }
    public string BillTypeWarehouse { get; set; }
    public string OrderType { get; set; }

    //Item Chilld
    public string ItemID { get; set; }
    public string ItemDescription { get; set; }
    public string BrandCode { get; set; }
    public string PackSize { get; set; }
}

领域模型

public class CostPageSelection
{
    public CostPageParent CostPageParent { get; set; }
    public List<ItemChild> ChildItems { get; set; }
}


//CostPageParent
public class CostPageParent
{
    public int? SelectedCostPageID { get; set; }
    public string CostPage { get; set; }
    public string Description { get; set; }
    public string Vendor { get; set; }
    public string VendorID { get; set; }
    public string BillTypeDirect { get; set; }
    public string BillTypeWarehouse { get; set; }
    public string OrderType { get; set; }
}

//ItemChild
public class ItemChild
{
    public int? SelectedItemID { get; set; }
    public string ItemID { get; set; }
    public string ItemDescription { get; set; }
    public string BrandCode { get; set; }
    public string PackSize { get; set; }
}

解决方法

从您的问题来看,您的数据库似乎包含父子关系的扁平层次结构,如果数据库架构已规范化以避免数据重复,则会更好:换句话说,每个CostPageRow行应包含对a的引用包含相关CostPageParent实例的不同表(但我假设您已经有一个正在运行的数据库,这不是一个选项).

要解决当前的问题,您需要从每个CostPageRow实例中提取定义单个组的属性(这些属性将形成新的CostPageParent实例),然后使用这些CostPageParent实例创建组作为唯一键,最后项目组到CostPageSelection的新实例(每个具有唯一的CostPageParent键).

在创建组代码后,您需要修改代码以使用IGrouping< T> .Key属性来获取组密钥:

var groups = costPageRows
    .GroupBy(x => new CostPageParent()
        {
            CostPage = x.CostPage,Description = x.Description,BillTypeDirect =  x.BillTypeDirect,BillTypeWarehouse = x.BillTypeWarehouse,OrderType = x.OrderType,Vendor = x.Vendor
        },new CostPageParentEqualityComparer())
    .Select(y => new CostPageSelection
        {
            CostPageParent = y.Key,ChildItems = y.Select(i => 
                new ItemChild()
                { 
                    BrandCode = i.BrandCode,ItemDescription = i.ItemDescription,ItemID = i.ItemID,PackSize = i.PackSize
                })
                .ToList()
        })
    .ToList();

请注意,您需要指定IEqualityComparer< CostPageParent>实现分组工作属性:

class CostPageParentEqualityComparer : IEqualityComparer<CostPageParent>
{
    public bool Equals(CostPageParent x,CostPageParent y)
    {
        if (x == null)
            return y == null;

        if (object.ReferenceEquals(x,y))
            return true;

        return 
            x.BillTypeDirect == y.BillTypeDirect &&
            x.BillTypeWarehouse == y.BillTypeWarehouse &&
            ...
    }

    public int GetHashCode(CostPageParent obj)
    {
        var x = 31;
        x = x * 17 + obj.BillTypeDirect.GetHashCode();
        x = x * 17 + obj.BillTypeWarehouse.GetHashCode();
        ...
        return x;
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读