简体   繁体   中英

EF Core 3.1 :How to merge these three queries in one?

This is my Modal class

public class Tag
    {
        public int Id { get; set; }
        public int UnitId { get; set; }
        public int MeasureId { get; set; }
        public int TagTypeId { get; set; }
}

i want fetch data from table and perform GroupBy on TagTypeId .the result i have mind as this json data:

Result:

[
    {
        "title": "Actual",
        "key": 1,
        "disabled": false,
        "child": [
            {
                "title": "valve 0036",
                "key": "Tag1",
                "disabled": true,
                "measure": "Celsius",
                "tagType": "Actual",
                "child": null
            },
            {
                "title": "valve 0036",
                "key": "Tag2",
                "disabled": true,
                "measure": "Celsius",
                "tagType": "Actual",
                "child": null
            },
            {
                "title": "valve 0036",
                "key": "Tag21",
                "disabled": true,
                "measure": "Celsius",
                "tagType": "Actual",
                "child": null
            }
           
        ]
    },
    {
        "title": "Virtual",
        "key": 2,
        "disabled": false,
        "child": [
            {
                "title": "valve 0036",
                "key": "Tag36",
                "disabled": true,
                "measure": "Celsius",
                "tagType": "Virtual",
                "child": null
            },
            {
                "title": "valve 0036",
                "key": "Tag37",
                "disabled": true,
                "measure": "Celsius",
                "tagType": "Virtual",
                "child": null
            }
        ]
    },
    {
        "title": "Lab",
        "key": 3,
        "disabled": false,
        "child": [
            {
                "title": "valve 0036",
                "key": "Tag38",
                "disabled": true,
                "measure": "Celsius",
                "tagType": "Lab",
                "child": null
            }
        ]
    }
]

i write this code works but i was forced use there query for do.

 var tagsDataActual = await _context
                .Tags.Where(x => x.TagTypeId == 1)
                .GroupBy(x => new { x.TagTypeId, x.TagType.Title })
                .Select(x => new TagDto
                {
                    Title = x.Key.Title,
                    Key = x.Key.TagTypeId.ToString(),
                    Child = _context.Tags.Where(x => x.TagTypeId == 1)
                     .Select(x => new TagDto
                     {
                         Title = x.Title,
                         Measure = x.Measure.Title,
                         Key = "Tag" + x.Id.ToString(),
                         TagType = x.TagType.Title,
                         Disabled = true,
                         Child = null
                     })
                }).ToListAsync();

            var tagsDataVirtual = await _context
               .Tags
               .Where(x => x.TagTypeId == 2)
               .GroupBy(x => new { x.TagTypeId, x.TagType.Title })
               .Select(xs => new TagDto
               {
                   Title = xs.Key.Title,
                   Child = _context.Tags.Where(x => x.TagTypeId == 2)
                    .Select(x => new TagDto
                    {
                        Title = x.Title,
                        Measure = x.Measure.Title,
                        Key = "Tag" + x.Id.ToString(),
                        TagType = x.TagType.Title,
                        Disabled = true,
                        Child = null
                    })
               }).ToListAsync();

            var tagsDataLab = await _context
           .Tags
           .Where(x => x.TagTypeId == 3)
           .GroupBy(x => new { x.TagTypeId, x.TagType.Title })
           .Select(xs => new TagDto
           {
               Title = xs.Key.Title,
               Child = _context.Tags.Where(x => x.TagTypeId == 3)
                .Select(x => new TagDto
                {
                    Title = x.Title,
                    Measure = x.Measure.Title,
                    Key = "Tag" + x.Id.ToString(),
                    TagType = x.TagType.Title,
                    Disabled = true,
                    Child = null
                })
           }).ToListAsync();
            var tagsData = tagsDataActual.Concat(tagsDataVirtual).Concat(tagsDataLab).ToList();
            return tagsData;

and this is TagDto Class

public class TagDto
{

    public string Title { get; set; }
    public string Key { get; set; }
    public bool Disabled { get; set; }
    public string Measure { get; set; }
    public string TagType { get; set; }
    public IEnumerable<TagDto> Child { get; set; }
}

is there any way for use one query instead of there? thanks...

Update your Where(...) to be like .Where(x => x.TagTypeId == 1 || x.TagTypeId == 2 || x.TagTypeId == 3) .

Update your Child = line as mentioned below. Here x is already Grouped list for respective TagTypeId , so you don't need to filter again. Just use Child = x.Select(y => new TagDto {...} . Don't use x again as it is used in outer scope .

Write your query like below.

var tagsData = await _context.Tags
                .Where(x => x.TagTypeId == 1 || x.TagTypeId == 2 || x.TagTypeId == 3)
                .GroupBy(x => new { x.TagTypeId, x.TagType.Title })
                .Select(x => new TagDto
                {
                    Title = x.Key.Title,
                    Key = x.Key.TagTypeId.ToString(),
                    Child = x.Select(y => new TagDto
                             {
                                 Title = y.Title,
                                 Measure = y.Measure.Title,
                                 Key = "Tag" + y.Id.ToString(),
                                 TagType = y.TagType.Title,
                                 Disabled = true,
                                 Child = null
                             })
                }).ToListAsync();

Edit Try like below query.

Update your Where(...) to be like .Where(x => x.TagTypeId == 1 || x.TagTypeId == 2 || x.TagTypeId == 3) .

Update your Where part in Child = _context.Tags.Where(y => y.TagTypeId == x.Key.TagTypeId) .

Complete query will be like below.

var tagsData = await _context.Tags
                .Where(x => x.TagTypeId == 1 || x.TagTypeId == 2 || x.TagTypeId == 3)
                .GroupBy(x => new { x.TagTypeId, x.TagType.Title })
                .Select(x => new TagDto
                {
                    Title = x.Key.Title,
                    Key = x.Key.TagTypeId.ToString(),
                    Child = _context.Tags
                            .Where(y => y.TagTypeId == x.Key.TagTypeId)
                            .Select(y => new TagDto
                             {
                                 Title = y.Title,
                                 Measure = y.Measure.Title,
                                 Key = "Tag" + y.Id.ToString(),
                                 TagType = y.TagType.Title,
                                 Disabled = true,
                                 Child = null
                             })
                }).ToListAsync();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM