LINQ для возврата различного значения по заданному столбцу c - PullRequest
2 голосов
/ 22 апреля 2020

У меня есть таблица Colour, подобная этой:

Id  Name    VendorId
--------------------
1   Purple  NULL
2   Blue    NULL
3   Black   NULL
4   Purple  1
5   Orange  1
6   Mauve   2

И я хочу получить все цвета с VendorId как NULL, если только у этого цвета Name нет записи с VendorId прикрепленный, например, для VendorId = 1 Я бы хотел

Id  Name    VendorId
--------------------
2   Blue    NULL
3   Black   NULL
4   Purple  1
5   Orange  1

Отметив, что Purple идентификатор строки 1 с NULL VendorId отсутствует в списке. Для Id = 2 я бы получил строки 1,2,3 и 6

Сначала я думал .Select .Distinct в Name, но мне нужен весь объект или хотя бы Id's

        var result = _context.Colours
            .Where(x => x.Vendor == null || x.Vendor.Id == vendorId)
            .Select(x => x.Name)
            .Distinct()
            .ToList();

но если я использую .Select(x => x.Id).Distinct(), тогда я получаю два экземпляра Purple

Как мне добиться этого в LINQ?

Редактировать:

Я только что попытался использовать

        var result = _context.Colours
            .Where(x => x.Vendor == null || x.Vendor.Id == vendorId)
            .OrderByDescending(x => x.Id)
            .GroupBy(x => x.Name)
            .Distinct()
            .ToList()
            .Select(x => x.First())
            .ToList();

Пытаясь получить все null и id = 1, затем упорядочить по убыванию Id и попробовать .GroupBy, но я получил Client side GroupBy is not supported.

Ответы [ 2 ]

1 голос
/ 22 апреля 2020

Этот работает для меня и дает ожидаемые результаты:

var idOrNameNotWithId = 
    colours.Where(x => x.VendorId == cid ||
    (!x.VendorId.HasValue && !colours.Where(x => x.VendorId == cid).Select(x => x.Name).ToList().Contains(x.Name)))
    .ToList();

Идея, лежащая в основе этого: все с ожидаемым cid (цветным идентификатором) или что-либо, что является нулевым, но только если, когда вы берете что-либо с идентификатором названия цвета там нет.

И полный рабочий метод. Я заимствовал определение коллекции colour из ответа @ Enigmativity.

static void Main(string[] args)
{
    Console.WriteLine("Hello World!");
    var colours = new[]
    {
        new { ID = 1, Name = "Purple", VendorId = (int?)null },
        new { ID = 2, Name = "Blue", VendorId = (int?)null },
        new { ID = 3, Name = "Black", VendorId = (int?)null },
        new { ID = 4, Name = "Purple", VendorId = (int?)1 },
        new { ID = 5, Name = "Orange", VendorId = (int?)1 },
        new { ID = 6, Name = "Mauve", VendorId = (int?)2 },
    };

    var cid = 2;

    var idOrNameNotWithId = 
        colours.Where(x => x.VendorId == cid ||
        (!x.VendorId.HasValue && !colours.Where(x => x.VendorId == cid).Select(x => x.Name).ToList().Contains(x.Name)))
        .ToList();
        }
    }
}
1 голос
/ 22 апреля 2020

Дайте это go:

var vendorId = 1;
var result =
    _context
        .Colours
        .Where(x => x.VendorId == null || x.VendorId == vendorId)
        .OrderByDescending(x => x.VendorId)
        .GroupBy(x => x.Name)
        .SelectMany(xs => xs.Take(1))
        .OrderBy(x => x.ID)
        .ToList();

С этим примером данных:

var colours = new []
{
    new { ID = 1, Name = "Purple", VendorId = (int?)null },
    new { ID = 2, Name = "Blue", VendorId = (int?)null },
    new { ID = 3, Name = "Black", VendorId = (int?)null },
    new { ID = 4, Name = "Purple", VendorId = (int?)1 },
    new { ID = 5, Name = "Orange", VendorId = (int?)1 },
    new { ID = 6, Name = "Mauve", VendorId = (int?)2 },
};

Я получаю этот результат:

result

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...