Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# EF Code First-从多对多表返回记录_C#_Entity Framework_Linq_Many To Many - Fatal编程技术网

C# EF Code First-从多对多表返回记录

C# EF Code First-从多对多表返回记录,c#,entity-framework,linq,many-to-many,C#,Entity Framework,Linq,Many To Many,我正在尝试使用实体框架和linq以平面方式获取m:m表中的所有记录 数据模型: public partial class Group { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public Guid GroupId { get; set; } [StringLength(100)] public string Name { get; set; } public v

我正在尝试使用实体框架和linq以平面方式获取m: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; }

}
以下是我在Linq中尝试的内容,但我得到了一个自引用循环错误:

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

这看起来应该相对容易,但我发现实体框架中的m:m可能有点棘手。任何帮助都将不胜感激

我很高兴您定义了多对多的两个虚拟集合,而没有指定连接表

您确实意识到,如果您不获取“组及其用户”,而是查询组和用户的左外部联接(您称之为平面方式),那么组属性将为每个用户重复一次又一次

但是,这是您的决定,您需要说服您的项目负责人,最好将同一组属性转移一百次,而不是只转移一次

您是对的,对于左外部联接,您需要执行
选择many
。我不知道您为什么决定使用
包含
而不是
选择

查询数据时,请始终使用选择,并仅选择实际计划使用的属性。仅当您计划更新获取的包含数据时,才使用包含

这在一对多关系中尤其有意义。如果您获取“学校及其学生”,并且Id为4的学校有1000名学生,那么您知道该学校的每个学生都有一个值为4的外键。将此值传递4次超过1000次是多么浪费啊

的其中一个重载有一个参数
resultSelector
,该参数将使用一个
和一个
用户
作为输入来创建结果。此版本非常适合您的需要

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

您能否发布
自引用循环错误的完整错误
,当我看到这一点时,我的假设是这很可能是由JSON序列化引起的。x=>x。用户将无法工作,因为类不可枚举。改为尝试db.Context.Users.Select(y=>new{id=y.UserId,FirstName=y.FirstName,LastName=y.LastName,DisplayName=y.DisplayName});这是一个非常常见的错误,在许多关于堆栈溢出的问题中都有涉及。解决方案总是:调整Json序列化程序设置或使用视图模型/DTO。谢谢Harald。这是有道理的,而且效果很好。我对EF code first和Linq有点生疏,因此我感谢您的建议和学习机会。
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);