C# 如何使用linq获取相关数据?

C# 如何使用linq获取相关数据?,c#,database,linq,entity-framework-core,C#,Database,Linq,Entity Framework Core,我有一张人员表和人员驾驶执照表。PersonnelDrivingLicense表中有多条记录与一名人员相关 我试图用linq获取人员和人员驾驶许可证数据,但我得到的是2条记录,而不是1条记录 以下是我的linq查询: from p in Personnel join pdl in PersonnelDrivingLicense on p.Id equals pdl.PersonnelId select new Personnel { Id = p.Id, PersonnelDri

我有一张人员表和人员驾驶执照表。PersonnelDrivingLicense表中有多条记录与一名人员相关

我试图用linq获取人员和人员驾驶许可证数据,但我得到的是2条记录,而不是1条记录

以下是我的linq查询:

from p in Personnel
join pdl in PersonnelDrivingLicense on p.Id equals pdl.PersonnelId
select new Personnel
{
    Id = p.Id,
    PersonnelDrivingLicense = new List<PersonnelDrivingLicense>
    {
        new PersonnelDrivinLicense
        {
             Id = pdl.Id,
             DrivingLicenseClass = pdl.DrivingLicenseClass
        }
    }
}
正确的结果应如下所示:

Id: 1,
PersonnelDrivingLicense:
    Id: 1,
    DrivingLicenseClass: B

    Id: 2,
    DrivingLicenseClass: C
我怎样才能得到上面想要的结果? 我应该如何编写正确的linq查询


谢谢。

您应该按Id对返回的人员对象进行分组。请尝试以下操作:

from p in Personnel
join pdl in PersonnelDrivingLicense on p.Id equals pdl.PersonnelId
group p by p.Id into g
select new Personnel
{
    Id = g.Key,
    PersonnelDrivingLicense = g.Select(x => x.PersonnelDrivingLicense).ToList()
}

如果您有一对多或多对多关系,并且您想要一个项目及其子项目,则应使用GroupJoin而不是Join

在您的情况下,您有
人员
人员驾驶执照
,可能是一对多关系:每个
人员
对象都有零个或多个
人员驾驶执照
。每个
PersonnelDrivingLicense
只属于一个
Personnel
对象,即外键
PersonnelId
所指的
Personnel

显然,您需要一系列
人员
对象,每个
人员
对象都有他/她的
人员驾驶执照
列表

// GroupJoin Personnel with PersonnelDrivingLicenses
var personnelWithTheirDrivingLicenses = myDbContext.Personnel
    .GroupJoin(myDbDcontext.PersonnelDrivingLicenses,

    // from every personnel object take the Id,
    personnel => personnel.Id,
    // from every driving license take the PersonnelId
    personnelDrivingLicence => personnelDrivingLicence.PersonnelId,

    // Take the Personnel, with all his matching driving licenses to make a new:
    (personnel, drivingLicenses) => new
    {
        // for optimal efficiency, Select only the properties you plan to use:
        Id = personnel.Id,
        Name = personnel.Name,
        ...

        DrivingLicenses = drivingLicenses
            .Where(drivingLicense => ...) // only if you don't want all his DrivingLicenses
            .Select(drivingLicense => new
            {
                // again, select only the properties you plan to use:
                Id = drivingLicense.Id,
                Type = drivingLicense.Type,
                ...

                // not needed, you already know the value:
                // PersonnelId = drivingLicense.PersonnelId,
            })
            .ToList(),
    });

如果您在人员和驾驶执照表(驾驶执照收集的导航属性)之间存在关系:
context.personal.Include(p=>p.DrivingLicenses)。ToList()
(内部)连接生成一个叉积结果,基本上每个连接键匹配一行。这就是为什么你会看到“重复”的结果。通过对行进行分组,可以解决此问题。此外,如果您使用的是实体框架,那么根据您的模型关系,有更简单的方法来实现这一点。您可以将实体模型添加到您的问题中吗?
// GroupJoin Personnel with PersonnelDrivingLicenses
var personnelWithTheirDrivingLicenses = myDbContext.Personnel
    .GroupJoin(myDbDcontext.PersonnelDrivingLicenses,

    // from every personnel object take the Id,
    personnel => personnel.Id,
    // from every driving license take the PersonnelId
    personnelDrivingLicence => personnelDrivingLicence.PersonnelId,

    // Take the Personnel, with all his matching driving licenses to make a new:
    (personnel, drivingLicenses) => new
    {
        // for optimal efficiency, Select only the properties you plan to use:
        Id = personnel.Id,
        Name = personnel.Name,
        ...

        DrivingLicenses = drivingLicenses
            .Where(drivingLicense => ...) // only if you don't want all his DrivingLicenses
            .Select(drivingLicense => new
            {
                // again, select only the properties you plan to use:
                Id = drivingLicense.Id,
                Type = drivingLicense.Type,
                ...

                // not needed, you already know the value:
                // PersonnelId = drivingLicense.PersonnelId,
            })
            .ToList(),
    });