C# 执行类似于字典格式的linq查询,使用groupby从另一个列表检索值

C# 执行类似于字典格式的linq查询,使用groupby从另一个列表检索值,c#,linq,many-to-many,todictionary,C#,Linq,Many To Many,Todictionary,我有表User和表项,其中表列表(包含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)

我有表User和表项,其中表列表(包含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,
);
用户表也具有与项表相同的模式,但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
var test1=来自obj.User中的p
p.项中的k
其中p.Userid==Userid//检索特定用户的项目
选择itemRes{itemid=k.itemid};
IEnumerable itemret=test1.ToList();
var query=来自对象用户中的p
p.项中的k
按itemret.Contains(k.itemid)将p.Userid分组到g//error1中
选择新结果{fitemid=g.Key,fUserid=g.ToList()};
IEnumerableoutput=query.ToDictionary(fitemid,fUserid)//错误2
第一个查询工作正常,而第二个查询抛出一些编译错误 这里出现的错误如下

错误1:IEnumerable不包含“Contains”的定义

错误2:名称fitemid在当前上下文中不存在,名称fUserid在当前上下文中不存在

这个班看起来像这样

public class Result
{
    public int fitemid { get; set; }
    public List<string> fUserid { get; set; }
}
公共类结果
{
公共int fitemid{get;set;}
公共列表融合器ID{get;set;}
}
我不熟悉linq概念,所以我不知道我的语法和定义是否正确。我在第一个查询中编写了一个函数来检索项目列表。在列表中每个项目的第二个查询中,我检索每个特定项目的用户

请帮我纠正这个问题

更新1:我错误地将查询转换为字典格式。@Gusman和@Alex为我指出了正确的方向,所以我将第二个查询转换为

IEnumerable query=来自对象用户中的p
p.项中的k
按itemret.Contains(k.itemid)将p.Userid分组到g//error1中
选择新结果{fitemid=g.Key,fUserid=g.ToList()};
错误2消失了

更新2:为了删除错误1,我按照@kwan245所说的做了

MyEntities obj=新的MyEntities();
var test1=来自对象用户中的p
p.项中的k
其中p.Userid==Userid//检索特定>用户的项目
选择k.itemid;
IEnumerable 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() };
IEnumerable query=来自对象用户中的p
p.项中的k
其中itemret.Contains(k.itemid)
按k.itemid将p.Userid分组为g//new error
选择新结果{fitemid=g.Key,fUserid=g.ToList()};
弹出的新错误是:LINQ to Entities无法识别方法“System.Collections.Generic.List
1[System.String]ToList[String](System.Collections.Generic.IEnumerable
1[System.String]),并且此方法无法转换为存储表达式


这可能是由于语法错误造成的,但正确的答案是什么?代码中有多个错误,例如:

  • 您不能像使用
    itemret.Contains(k.itemid)
    尝试的那样对函数调用进行
    分组
  • IEnumerator输出
    不是字典,因此无法将调用
    query.ToDictionary(…)
    的结果分配给它
  • 您的
    查询
    实际上被键入以返回一个
    IEnumerable
    (请参见它的
    select
    语句)。那你为什么要把它转换成字典呢
  • 无法使用所使用的
    ToDictionary
    语法创建词典。它的可用重载如下所示,并且所有这些重载都需要lambda表达式来映射从给定的
    IEnumerable
    输入使用的
    键和
    值属性
此外,在编辑之后,我还不太清楚
列表
用户
项目
之间的关系,因为您没有在问题中提供它们的声明。此外,尚不清楚MyEntities到底是什么

现在(在其他信息可用之前),我将假设以下内容:
MyEntities
是包含“列表
”、
User
Item
集合的上下文,其中
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; }
}
这些都是推测性的选项,我可以根据您问题中的当前信息提出。

1)您使用的是什么版本的实体框架?仅在EF4之后支持Contains。
2) 使用函数式ToDictionary方法,如中所示

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();
MyEntities obj=新的MyEntities();
var test1=来自对象用户中的p
p.项中的k
其中p.Userid==Userid//检索特定>用户的项目
选择k.itemid;
IEnumerable itemret=test1.ToList();

假设itemid为int

文件开头有“using System.Linq”吗?当然有,否则第一个查询也不起作用,对吧???不,如果用户类是IQuerable,它会起作用。Contains方法是System.Linq中IEnumerable的扩展,如果它不存在,应该是因为System.Linq命名空间未被引用…引用存在于文件中。我不确定错误1,但错误2是因为ToDictionary将返回字典,而不是IEnumerator。我在这里使用的对象是我的
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()
    };
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();