我正在使用MVC3和实体框架,但我来到了需要来自不同表的更多数据的地步。通常我会做这样的事情来从表中获取数据:
Table: Users
id
username
在代码中,我会做这样的事情来获取所有用户:
public static IEnumerable<Users> GetUsers( int userId )
{
MyEntities ent = new MyEntities();
return from g in ent.Users
where g.OwnerUserId == userId
select g;
}
所以这会让我的所有用户都回来。
但是用户可以加入群组,我必须获取特定群组中的所有用户名。
Table: userGroups
id
fk_user_id
fk_group_id
现在,如果我使用此代码:
public static IEnumerable<userGroups> GetUsersFromGroup( int groupId )
{
MyEntities ent = new MyEntities();
return from g in ent.userGroups
where g.OwnerUserId == userId
select g;
}
现在很明显,这只会返回“userGroups”表中的数据。但不知何故,我还需要Users表中的用户名。我怎样才能获得这些数据并仍然将我的“userGroups”作为IEnumerable返回?
在SQL中,我只是做一个LEFT JOIN,但我无法弄清楚它是如何工作的。
答案 0 :(得分:5)
这样的事情可能是:
var query = from g in ent.userGroups
join u in ent.Users on g.fk_user_id equals u.userID
select new { g, u, });
或使用LEFT JOIN
var query = (from g in ent.userGroups
from u in ent.Users.Where(a => a.fk_user_id == u.userID).DefaultIfEmpty()
select new { g, u, });
答案 1 :(得分:3)
var query = from ug in ent.userGroups
join u in ent.Users on ug.OwnerUserId = ug.userID
select new
{
Name = u.UserName,
Id = u.userID
Group = ug.GroupName
};
如果您需要左连接,则需要DefaultIfEmpty。
请查看以下文章:
答案 2 :(得分:2)
上述查询将要求您更改方法签名,这可能是很多非常痛苦的工作,具体取决于您设置的位置。 Arion尤其完全模仿你所谈论的左连接行为(这很好,因为你知道Entity正在做什么),但是你需要将你的返回类型更改为Tuple<userGroups, Users>
或者其他类似的东西。性质。
您可以尝试更新userGroups poco以将nav属性包含到Users
表中。如果我正确理解您发布的问题,那么您就拥有一对多的关系。在这种情况下,您可以按如下方式更改poco:
public class userGroups
{
public int ID { get; set; }
public string GroupName { get; set; }
public virtual ICollection<Users> Users { get; set; }
}
public class Users
{
public int ID { get; set; }
public string Name { get; set; }
public virtual userGroups UserGroup { get; set; }
}
但是,您在原始问题中发布的名称不是Entity认为的标准化命名,因此您可能需要使用here所述的数据注释。 Ctrl-F“ForeignKey”如果你在找到它时遇到一些麻烦,它对整个数据注释来说是一个很大的信息。
好处是,如果您这样链接,您将永远不必担心再次加入。您只需访问userGroups上的Users集合,就可以访问,加入和计算所有这些内容。