EF代码第一 - 返回记录从多对多表

问题描述 投票:0回答:1

我试图让在M的所有记录:在平坦的方式与实体框架和LINQ M表中。

数据模型:

public partial class Group
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid GroupId { get; set; }

    [StringLength(100)]
    public string Name { get; set; }

    public virtual ICollection<User> Users { get; set; }

}

public partial class User
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid UserId { get; set; } = new Guid();

    [StringLength(100)]
    public string FirstName { get; set; }

    [StringLength(100)]
    public string LastName { get; set; }

    [StringLength(255)]
    public string DisplayName { get; set; }


    public virtual ICollection<Group> Groups { get; set; }

}

下面是SQL其中拉回到我在寻找数据集中的查询:

select g.GroupId, g.[Name], u.DisplayName, u.UserId 
from [Group] g, [User] u, [GroupUsers] gu
where g.GroupId = gu.Group_GroupId
and gu.User_UserId = u.UserId
order by g.[Name]

这里就是我想在LINQ的,但我发现了一个自我循环引用错误:

using (RequestContext ctx = new RequestContext())
{
     return ctx.Groups.SelectMany(x => x.Users).Include(x => x.Groups).ToList();
}

这似乎是它应该是比较容易的,但我发现M:M关系在实体框架可以是一个有点棘手。任何帮助,将不胜感激。

c# entity-framework linq many-to-many
1个回答
1
投票

我很高兴你定义了许多一对多的两个虚拟集合,而不指定联接表!

你一定要明白,如果你不取“组,他们的用户”,而是查询左外连接的组和用户(你把那个叫平时装),组属性将被重复了一遍又一遍,每的用户?

但是,嘿,这是你的决定,这是由你来说服你的项目负责人,这是更好百倍传递同一组属性,而不是把它们转移只有一次的。

你说的没错,一个左外连接,你需要做一个SelectMany。我不知道为什么你决定改用IncludeSelect

当查询数据始终使用选择,选择只有你实际计划使用的性能。如果你打算更新获取的数据包括仅使用include。

这样做的原因是一个一对多的关系,特别有意义。如果您取“与学生的学校”,并与学校ID 4有1000名学生,那么你知道这所学校的每个学生都将有一个价值4的外键多么大的浪费超过1000次传递这个值4 !

一个Enumerable.SelectMany的重载的具有参数resultSelector,这将需要一个Group和一个User作为输入以生成结果。这个版本是最适合你的需要

var result = dbContext.Groups.SelectMany(
    group => group.Users,
    (group, user) => new
    {
        // Select the Group properties you plan to use
        GroupId = group.GroupId,
        GroupName = group.Name,
        ...

        // Select the User properties you plan to use
        UserId = user.UserId,
        UserName = user.DisplayName,
        ...
    })

    // if desired do some ordering
    .OrderBy(joinedItem => joinedItem.GroupName);
© www.soinside.com 2019 - 2024. All rights reserved.