Выполнение запроса linq, аналогичного формату словаря, с использованием groupby для извлечения значения из другого списка

У меня есть таблица User и Items, где в таблице List есть отношение многие ко многим (которое содержит UserId и ItemId). Сейчас я пытаюсь найти для каждого элемента все его пользователи. Схема для таблиц

CREATE TABLE dbo.Item
(
itemid int identity(1,1) not null,
Item_Name varchar(30) not null,
PRIMARY KEY (itemid)
);

CREATE TABLE dbo.List
(
itemid int not null,
Userid varchar(11) not null,
);

Пользовательская таблица также имеет ту же схему, что и таблица Item, но Userid имеет тип varchar(11). Строка подключения называется MyEntities

MyEntities obj = new MyEntities();

Запрос linq имеет формат

var test1 = from p in obj.User
            from k in p.Item
            where p.Userid == Userid //retrieving the items for a particular user
            select itemRes { itemid = k.itemid };
IEnumerable<itemRes> itemret = test1.ToList();


var query = from p in obj.User
            from k in p.Item
            group p.Userid by itemret.Contains(k.itemid) into g// error1
            select new Result { fitemid = g.Key, fUserid = g.ToList() };
IEnumerable<Result>output = query.ToDictionary(fitemid, fUserid);//error2

Первый запрос работает отлично, в то время как второй запрос выдает некоторую ошибку компиляции. Здесь ошибки возникают следующим образом

Ошибка 1:IEnumerable не содержит определения для "Contains"

Ошибка 2: имя fitemid не существует в текущем контексте, имя fUserid не существует в текущем контексте

Класс выглядит так

public class Result
{
    public int fitemid { get; set; }
    public List<string> fUserid { get; set; }
}

Я новичок в понятиях linq, поэтому я не знаю, правильный ли мой синтаксис и определение. Я написал первый запрос для получения списка элементов. Во втором запросе для каждого элемента в списке я извлекаю пользователей каждого конкретного элемента.

Пожалуйста, помогите мне исправить запрос....

Обновление 1: я ошибся при преобразовании запроса в формат toDictionary.@Gusman и @Alex указали мне правильное направление, поэтому я преобразовал второй запрос как

 IEnumerable<Result> query = from p in obj.User
            from k in p.Item
            group p.Userid by itemret.Contains(k.itemid) into g// error1
            select new Result { fitemid = g.Key, fUserid = g.ToList() };

и ошибка2 ушла

Обновление 2: чтобы удалить ошибку 1, я сделал то, что сказал @kwan245

MyEntities obj = new MyEntities();
var test1 = from p in obj.User
            from k in p.Item
            where p.Userid == Userid //retrieving the items for a particular >user
            select k.itemid ;
IEnumerable<int> itemret = test1.ToList();

и второй запрос как этот

IEnumerable<Result> query = from p in obj.User
                            from k in p.Item
                            where itemret.Contains(k.itemid)
                            group p.Userid by k.itemid into g// new error
                            select new Result { fitemid = g.Key, fUserid = g.ToList() };

выскочила новая ошибка: LINQ to Entities не распознает метод 'System.Collections.Generic.List1[System.String] ToList[String](System.Collections.Generic.IEnumerable1 [System.String]) ', и этот метод нельзя преобразовать в выражение хранилища

Это может быть связано с неправильным синтаксисом, но каков будет правильный ответ

2 ответа

1) Какую версию Entity Framework вы использовали? Содержит поддерживается только после EF4.
2) используйте функционал для метода ToDictionary, как показано на https://msdn.microsoft.com/en-us/library/bb549277%28v=vs.95%29.aspx

3) Попробуйте изменить код на:

MyEntities obj = new MyEntities();
var test1 = from p in obj.User
            from k in p.Item
            where p.Userid == Userid //retrieving the items for a particular >user
            select k.itemid ;

IEnumerable<int> itemret = test1.ToList();

Предполагая, что itemid является int

В вашем коде несколько ошибок, например:

  • Ты не можешь group by вызов функции, как вы пытались с itemret.Contains(k.itemid),
  • IEnumerator<Result> output это не словарь, поэтому вы не можете присвоить результат вызова query.ToDictionary(...) к этому.
  • Ваш query на самом деле набирается, чтобы вернуть IEnumerable<Result> (увидеть это select заявление). Так почему вы хотите преобразовать его в словарь?
  • Вы не можете создать словарь, используя ToDictionary Синтаксис вы использовали. Его доступные перегрузки перечислены здесь, и все они требуют лямбда-выражений для сопоставления key а также value свойства использовать из данного IEnumerable<T> вход.

Также после вашего редактирования мне не совсем понятно, как соотносятся List, User а также Item, потому что вы не предоставили их объявления класса в вашем вопросе. Кроме того, неясно, что MyEntities точно есть.

На данный момент (пока не станет доступной другая информация), я буду предполагать следующее: MyEntities Ваш контекст содержит список,пользовательandВещьcollections, where theКоллекция List` представляет сопоставление "многие ко многим" между пользователями и элементами. Затем вы можете получить свой результат в одном запросе

var result = 
    from pair in obj.List
    group pair by pair.itemid into g
    select new Result {
        fitemid = g.Key,
        fUserid = g.Select(x => x.Userid).ToList()
    };

Если твой MyEntities содержит только User а также Item коллекции, я предполагаю, что их объявления класса следующие:

public class Item
{
    public int itemid { get; set; }
    public string Item_Name { get; set; }
    public virtual ICollection<User> Users { get; set; }
}

public class User
{
    public string userid { get; set; }
    public string User_Name { get; set; }
    public virtual ICollection<Item> Items { get; set; }
}

Который сделает ваш запрос:

var result = 
    from item in obj.Item
    select new Result {
        fitemid = item.itemid,
        fUserid = item.Users.Select(x => x.userid).ToList()
    };

Это все умозрительные варианты, которые я могу придумать, основываясь на текущей информации в вашем вопросе.

Другие вопросы по тегам