Почему Linq возвращает только один объект, когда фильтры не используются

Я действительно не знаю, как объяснить этот вопрос. Извините, если это дублированный пост. Этот код ниже работает нормально. Верните мне продукт с идентификатором 1031, и когда я запущу фильтр (где), я получу тот же продукт (потому что он находится и в отделе, и в категории). ХОРОШО! Но когда я удаляю where 1031 (вторая строка кода), он больше не работает. Атрибут IEnumerable с именем GroupsID имеет только одно значение внутри (отдела). Это очень странно. Когда я помещаю product.id == 1031, атрибут имеет 2 значения (49 и 137), но когда я удаляю, где product.id == 1031, он возвращает только значение первой группы (отдел) для каждого продукта. Все продукты в моем списке имеют только одно значение (в большинстве случаев 49).

   model.Products = from product in context.Products
                        where product.ID == 1031
                        orderby Guid.NewGuid()
                        select new ProductViewModel()
                        {
                            ID = product.ID,
                            FullDescription = product.FullDescription,
                            FileName = (from image in product.ProductImages
                                        select image.FileName).FirstOrDefault(),
                            Price = (from priceList in product.PriceListProducts
                                    select priceList.Price).FirstOrDefault(),
                            GroupsID = (from related in product.ProductGroupRelateds
                                        select related.ProductGroup_ID)
                        };

    CategoryViewModel ctg = model.Categories.Where(categ => categ.FriendlyUrl.ToLower().Equals(filter.ToLower()) || categ.FriendlyUrl.ToLower().Equals(categoryURL.ToLower())).Select(categ => new CategoryViewModel() { ID = categ.ID, Name = categ.Name, FriendlyUrl = categ.FriendlyUrl, Index = categ.Index }).DefaultIfEmpty(null).First();
    if (ctg != null)
        model.Products = model.Products.Where(product => product.GroupsID.Contains(ctg.ID));

    DepartmentViewModel dpt = model.Departments.Where(depto => depto.FriendlyUrl.ToLower().Equals(filter.ToLower()) || depto.FriendlyUrl.ToLower().Equals(departmentURL.ToLower())).Select(depto => new DepartmentViewModel() { ID = depto.ID, Name = depto.Name, FriendlyUrl = depto.FriendlyUrl, Index = depto.Index }).DefaultIfEmpty(null).First();
    if (dpt != null)
        model.Products = model.Products.Where(product => product.GroupsID.Contains(dpt.ID));

person Leandro De Mello Fagundes    schedule 19.04.2013    source источник
comment
Что вы пытаетесь сделать с orderby Guid.NewGuid()?   -  person Tim S.    schedule 19.04.2013
comment
@ТимС. после удаления заказа по его нормальному рабочему состоянию: | спасибо за все, что ты когда-либо делал :D rofl   -  person Leandro De Mello Fagundes    schedule 19.04.2013
comment
Отлично, сделаю ответ.   -  person Tim S.    schedule 19.04.2013


Ответы (1)


Удалить orderby Guid.NewGuid(). В целом это не лучший способ перетасовки, а в некоторых случаях он может сломать ваш код. Реализуйте перетасовку лучше, например. см. Является ли использование Random и OrderBy хорошим алгоритмом перемешивания? или Метод расширения в IEnumerable, необходимый для перетасовки. Короткая версия заключается в том, что это код, который вы можете использовать:

public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng)
{
    T[] elements = source.ToArray();
    for (int i = elements.Length - 1; i >= 0; i--)
    {
        // Swap element "i" with a random earlier element it (or itself)
        // ... except we don't really need to swap it fully, as we can
        // return it immediately, and afterwards it's irrelevant.
        int swapIndex = rng.Next(i + 1);
        yield return elements[swapIndex];
        elements[swapIndex] = elements[i];
    }
}
person Tim S.    schedule 19.04.2013