C# EF核心。如何将(左)联接表提取为集合?

C# EF核心。如何将(左)联接表提取为集合?,c#,.net,entity-framework,linq,entity-framework-core,C#,.net,Entity Framework,Linq,Entity Framework Core,我需要有关在上下文linq语法表达式中将联接表提取为集合的帮助 public class Computer { public int Id { get; set; } public string Name { get; set; } } public class Component { public int Id { get; set; } public string Name { get; set; } public int ComputerId { get;

我需要有关在上下文linq语法表达式中将联接表提取为集合的帮助

public class Computer
{
   public int Id { get; set; }
   public string Name { get; set; }
}

public class Component
{
   public int Id { get; set; }
   public string Name { get; set; }

   public int ComputerId { get; set; } //FK
   public Computer Computer { get; set; } //HasOne(Computer).WithMany().HasFK(ComputerId)
}
计算机没有对组件的反向引用

需要通过Linq语法选择具有相关组件的计算机

(from computer in db.Computers
join component in db.Components on computer.Id equals component.ComputerId into components //|  JOINED
from component in components.DefaultIfEmpty()                                              //|  TABLE
select new ComputerFullData
{
   Computer = computer,
   Components = components // <-- collection
})
........other code
(数据库计算机中的计算机)
将数据库中的组件连接到计算机上的组件。Id等于component.ComputerId,将其连接到组件//|连接
从components.DefaultIfEmpty()/|表中的组件
选择新的ComputerFullData
{
计算机,
Components=Components/backref属性,这样我就可以通过调用Include(x=>x.Components)提取组件集合,这实际上是像我的示例中那样的还原连接。在这种情况下,我可能无法访问组件集合


如何通过Linq实现同样的效果?

这在EF Core中非常适合我:

public class Computer
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class Component
{
    public int Id { get; set; }
    public string Name { get; set; }

    public int ComputerId { get; set; }
    public Computer Computer { get; set; }
}

public class Db : DbContext
{
    public static readonly ILoggerFactory MyLoggerFactory
        = LoggerFactory.Create(builder => builder.AddConsole());

    public DbSet<Component> Components { get; set; }

    public DbSet<Computer> Computers { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder
            .UseLoggerFactory(MyLoggerFactory)
            .UseSqlServer(@"Server=(localdb)\mssqllocaldb; Database=demo;Integrated Security=True");
    }
}

class Program
{
    static void Main(string[] args)
    {
        using (var db = new Db())
        {
            db.Database.EnsureCreated();

            db.Components.Add(
                new Component
                {
                    Computer = new Computer
                    {
                        Name = "Fred"
                    },
                    Name = "Fred component"
                });

            db.SaveChanges();
        }

        using (var db = new Db())
        {
            var computersWithComponents =
                (from c in db.Computers
                 select new
                 {
                     Computer = c,
                     Components = (from cp in db.Components
                                   where cp.ComputerId == c.Id
                                   select cp).ToList()
                 }).ToList();
        }
    }
}

出于兴趣,我知道这不是对您的问题的直接回答,为什么您拒绝在您的模型上使用
组件的导航属性呢?我经常发现使用EF时,只做有效的事情,而不是过分努力地获得我想要的模型是有帮助的。(如果我对所需对象的形状有非常具体的要求,我可能有两个类层次结构——一个是EF惯用的EF数据库模型,另一个是我的首选模型,带有在两者之间转换的方法。)无论如何,在这种情况下,想要得到你想要的东西并不难,所以在这里可能有点过头了。

这对我来说在EF Core中非常有效:

public class Computer
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class Component
{
    public int Id { get; set; }
    public string Name { get; set; }

    public int ComputerId { get; set; }
    public Computer Computer { get; set; }
}

public class Db : DbContext
{
    public static readonly ILoggerFactory MyLoggerFactory
        = LoggerFactory.Create(builder => builder.AddConsole());

    public DbSet<Component> Components { get; set; }

    public DbSet<Computer> Computers { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder
            .UseLoggerFactory(MyLoggerFactory)
            .UseSqlServer(@"Server=(localdb)\mssqllocaldb; Database=demo;Integrated Security=True");
    }
}

class Program
{
    static void Main(string[] args)
    {
        using (var db = new Db())
        {
            db.Database.EnsureCreated();

            db.Components.Add(
                new Component
                {
                    Computer = new Computer
                    {
                        Name = "Fred"
                    },
                    Name = "Fred component"
                });

            db.SaveChanges();
        }

        using (var db = new Db())
        {
            var computersWithComponents =
                (from c in db.Computers
                 select new
                 {
                     Computer = c,
                     Components = (from cp in db.Components
                                   where cp.ComputerId == c.Id
                                   select cp).ToList()
                 }).ToList();
        }
    }
}

出于兴趣,我知道这不是对您的问题的直接回答,为什么您拒绝在您的模型上使用
组件的导航属性呢?我经常发现使用EF时,只做有效的事情,而不是过分努力地获得我想要的模型是有帮助的。(如果我对所需对象的形状有非常具体的要求,我可能有两个类层次结构——一个是EF惯用的EF数据库模型,另一个是我的首选模型,带有在两者之间转换的方法。)无论如何,在这种情况下,想要得到你想要的东西并不难,所以这可能是过火了。

谢谢你的努力。我在示例中使用了EF Core 3。事实上,问题不在于请求本身,而在于接下来发生的事情。接下来,使用了AutoMapper,但配置不正确。停止使用后,我注意到请求正在正确生成和执行。感谢您的努力。我在示例中使用了EF Core 3。事实上,问题不在于请求本身,而在于接下来发生的事情。接下来,使用了AutoMapper,但配置不正确。停止使用它后,我注意到请求正在正确生成和执行。