我需要帮助将联接表提取为上下文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
但是,如果计算机具有 ICollection
如何通过Linq实现相同的目标?
答案 0 :(得分:2)
这在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();
}
}
}
这很像您在SQL中编写的内容。我很高兴发现在这样的子查询中引用上下文(db
)对于EF查询提供程序是可接受的,并且生成的SQL与我可能手工编写的内容类似:
SELECT [c].[Id], [c].[Name], [c0].[Id], [c0].[ComputerId], [c0].[Name]
FROM [Computers] AS [c]
LEFT JOIN [Components] AS [c0] ON [c].[Id] = [c0].[ComputerId]
ORDER BY [c].[Id], [c0].[Id]
出于兴趣-我知道这不是您问题的直接答案-为什么您拒绝在模型上拥有Components
的导航属性?我经常在EF中发现,做一些有效的工作会有所帮助,而不是过度努力以获取我想要的模型。 (如果我对所需对象的形状有非常特定的要求,则可能会有两个类层次结构-EF特有的EF数据库模型,以及我的首选模型,其中包含在两者之间进行转换的方法。)无论如何,在在这种情况下,获取您想要的东西并不难,因此在这里可能会显得过大。