2015-04-29 1 views
0

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

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, 
); 

таблица Пользователь также имеет ту же схему, как элементу таблицы, но 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 не содержит определения для «Содержит»

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

Класс выглядит следующим образом

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

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

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

Update1:. Я был неправ о преобразовании запроса в формат ToDictionary @ Гусман и @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() }; 

и Error2 ушел

Update 2: Для убр е Error1, я сделал то, что @ 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 к Entities не распознает метод «System.Collections .Generic.List 1[System.String] ToList[String](System.Collections.Generic.IEnumerable 1 [System.String]) ', и этот метод не может быть переведен в выражение хранилища

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

+0

У вас есть "с помощью System.Linq" в начале файла? – Gusman

+0

Да, конечно, в противном случае первый запрос не будет работать, правильно ??? – Amalpriya

+0

Нет, это сработает, если класс User является IQueriable. метод Contains является расширением IEnumerable в System.Linq, если он не существует, это должно быть потому, что пространство имен System.Linq не ссылается ... – Gusman

ответ

1

Есть несколько ошибок в коде, как:

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

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

На данный момент (пока другая информация не будет доступна), я буду считать следующее: MyEntities ваш контекст, содержащий «списка , пользователя and Item 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() 
    }; 

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

+0

Объект obj, который я использую здесь, - это объект подключения объекта (см. Отредактированный код). Поскольку они имеют отношение «многие-ко-многим», я должен использовать навигацию для ссылки на таблицы. Я пытаюсь найти похожих пользователей (например, пользователей, у которых есть общие элементы). Поэтому для пользователя я нахожу все его предметы. Тогда для каждого элемента я нахожу его пользователей, поэтому я могу разработать свой код для сортировки других пользователей на основе сходства с текущим пользователем – Amalpriya

+0

Как использовать groupby только для ключевых слов в списке? – Amalpriya

+0

@Amalpriya Пожалуйста, добавьте к вашему вопросу (1) объявление класса 'User', (2) объявление класса' Item' (3) Если в вашем контексте базы данных есть 'DbSet Items '(4) Каков тип 'MyEntities'. – Alex

1

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 является ИНТ

+0

Я использую Entity Framework 5.0 – Amalpriya

+0

Похоже, проблема заключается в том, что вы пытаетесь использовать IEnumerable .Contains (int)? вместо IEnumerable .Contains (int), так что моё предложение изменить до выше – kwangsa

+0

Похоже, k.itemid - это строка, поэтому сменить Список в список kwangsa