![](/img/trans.png)
[英]Why EF Core automatically load related entities when property referring to the entity is accessed in Select method of Linq?
[英]EF LINQ method for related entities
我正在尝试使用扩展方法和 EF 代码编写一个 LINQ 查询,首先遍历 3 个相关实体。 CpeDefinition & PaperMachine 实体与 Tag 实体具有多对多关系。
我有 2 个用于此查询的静态输入,1 个用于 Cpe Id,另一个用于标记名称。
我想在用户选择的 id 上获取 CpeDefinition 记录,然后对于该 Cpe 记录,我想获取映射到该 Cpe 的所有匹配标签,然后我想通过用户输入的标签名称和冒号过滤这些结果标签。 最后,从这些结果标签中,我想将 PaperMachine 记录映射到这些标签。
public class Tag {
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<CpeDefinition> CpeDefinitions { get; set; }
public virtual ICollection<PaperMachine> PaperMachines { get; set; }
}
public class CpeDefinition
{
public int Id { get; set; }
public string Title { get; set; }
public virtual ICollection<Tag> Tags { get; set; }
}
public class PaperMachine
{
public int Id { get; set; }
public string Type { get; set; }
public string Plant { get; set; }
public string Line { get; set; }
public virtual ICollection<Tag> Tags { get; set; }
}
modelBuilder.Entity<PaperMachine>()
.HasMany<Tag>(p => p.Tags)
.WithMany(t => t.PaperMachines)
.Map(pt => {
pt.MapLeftKey("PaperMachineId");
pt.MapRightKey("TagId");
pt.ToTable("PaperMachinesTags");
});
modelBuilder.Entity<CpeDefinition>()
.HasMany<Tag>(d => d.Tags)
.WithMany(t => t.CpeDefinitions)
.Map(dt => {
dt.MapLeftKey("CpeDefinitionId");
dt.MapRightKey("TagId");
dt.ToTable("CpeDefinitionsTags");
最初我有这个查询,它几乎让我到达那里,但它没有通过匹配的 CpeDefinition 过滤标签(它返回与用户输入的标签匹配的所有造纸机,但不是用户选择的 Cpe:
string tag = "SiteA";
var taggedPaperMachines = db.Tags
.Where(t => t.Name.Contains(String.Concat(tag, ":")))
.Select(p => new
{
p.PaperMachines.FirstOrDefault().Id,
p.PaperMachines.FirstOrDefault().Line,
p.PaperMachines.FirstOrDefault().Plant,
p.PaperMachines.FirstOrDefault().Type
}).ToList()
.Select(pm => new PaperMachine
{
Id = pm.Id,
Line = pm.Line,
Plant = pm.Plant,
Type = pm.Type
});
我尝试将 Cpe 和标签放在一起,但我收到了一个空错误,我不明白为什么,因为我知道数据库表中有一个 Id = 1 的 Cpe:
转换为值类型 'System.Int32' 失败,因为具体化值为 null。 结果类型的泛型参数或查询必须使用可空类型
int CpeId = 1;
string TagName = "SiteA";
var temp1 = db.CpeDefinitions
.Where(cd => cd.Id == CpeId)
.Select(cd => new
{
cd.Tags.FirstOrDefault().Id,
cd.Tags.FirstOrDefault().Name
})
.ToList()
.Select(t => new Tag
{
Id = t.Id,
Name = t.Name
});
在一个完美的世界中,我希望将所有这些逻辑都包含在一个查询中,但此时不介意将第二个查询的结果推送到第一个查询中。
好简单 :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
DataBase db = new DataBase();
string tag = "SiteA";
var query = (from t in db.Tags
join c in db.CpeDefinitions on t.Id equals c.Id
select new { tag = t, definition = c }
).ToList();
List<PaperMachine> paperMachines = query.Where(x => x.tag.Name == (tag + ":"))
.SelectMany(x => x.tag.PaperMachines).ToList();
}
}
public class DataBase
{
public List<Tag> Tags { get; set; }
public List<CpeDefinition> CpeDefinitions { get; set; }
public List<PaperMachine> PaperMachines { get; set; }
}
public class Tag
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<CpeDefinition> CpeDefinitions { get; set; }
public virtual ICollection<PaperMachine> PaperMachines { get; set; }
}
public class CpeDefinition
{
public int Id { get; set; }
public string Title { get; set; }
public virtual ICollection<Tag> Tags { get; set; }
}
public class PaperMachine
{
public int Id { get; set; }
public string Type { get; set; }
public string Plant { get; set; }
public string Line { get; set; }
public virtual ICollection<Tag> Tags { get; set; }
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.