Выполнение запроса 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.IEnumerable
1 [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()
};
Это все умозрительные варианты, которые я могу придумать, основываясь на текущей информации в вашем вопросе.