需要包含()相关实体但没有选择这样做
Need to Include() related entities but no option to do so
我不确定如何表达这个问题的标题所以让我解释一下。
我需要 select 我的数据库中的大部分实体类型,使用 .Include 到 select 它是相关实体,但同时只 select 实体标识符所在的实体等于字符串数组中的 ID 之一。
我的代码如下:
List<TSRCategory> electives = new List<TSRCategory>();
foreach (var i in client.Electives.Split('&'))
{
int id = Int32.Parse(i);
electives.Add(db.TSRCategories.Find(id));
}
这正确 selects TSRCategories 是选修课 ID 列表的一部分,但不包括相关实体。我正在使用这段代码:
TSRCategories = db.TSRCategories.Include("Competencies.CompetencySkills").ToList();
但这不只是 select 所选的选修课。我理想中寻找的是这样的东西:
List<TSRCategory> electives = new List<TSRCategory>();
foreach (var i in client.Electives.Split('&'))
{
int id = Int32.Parse(i);
electives.Add(db.TSRCategories.Find(id));
}
TSRCategories = electives.Include("Competencies.CompetencySkills").ToList();
当然,无论出于何种原因,这都无法完成(关于为什么无法完成,我实际上不知道该在网上搜索什么!)。 Electives 是一个以 & 作为分隔符的字符串,用于将 ID 分隔到一个数组中。 TSRCategories 包含 Competencies,Competencies 包含 CompetencySkills。有没有一种方法可以在几行代码中有效地做到这一点?
using System.Data.Entity;
from x in db.Z.Include(x => x.Competencies)
.Include(x => x.Competencies.CompetencySkills)
select a.b.c;
按给定的 ID 列表搜索:
int[] ids = new int[0]; // or List<int>
from x in db.Z
where ids.Contains(x.Id)
select a.b.c;
你会发现,将关联的id一个一个地取出来,查询性能会很差。您可以通过首先投影所有需要的 id 的列表来一次性获取它们(我在这里假定了键名 ElectiveId
):
var electiveIds = client.Electives.Split('&')
.Select(i => Int32.Parse(i))
.ToArray();
var electives = db.TSRCategories
.Include(t => t.Competencies.Select(c => c.CompetencySkills))
.Where(tsr => electiveIds.Contains(tsr.ElectiveId))
.ToList();
但要提到的一件事是,将 ids
存储在由定界符连接的单个字符串字段中违反了数据库规范化。相反,您应该创建一个新的联结点 table,例如ClientElectives
其中 link 以规范化方式与客户关联的选修课 (ClientId, ElectiveId)
。这也将简化您的 EF 检索代码。
编辑
根据 documentation 中的示例,我应该使用 .Select
来指定预先加载的深度(而不是 .SelectMany
或其他扩展方法)。
我不确定如何表达这个问题的标题所以让我解释一下。 我需要 select 我的数据库中的大部分实体类型,使用 .Include 到 select 它是相关实体,但同时只 select 实体标识符所在的实体等于字符串数组中的 ID 之一。
我的代码如下:
List<TSRCategory> electives = new List<TSRCategory>();
foreach (var i in client.Electives.Split('&'))
{
int id = Int32.Parse(i);
electives.Add(db.TSRCategories.Find(id));
}
这正确 selects TSRCategories 是选修课 ID 列表的一部分,但不包括相关实体。我正在使用这段代码:
TSRCategories = db.TSRCategories.Include("Competencies.CompetencySkills").ToList();
但这不只是 select 所选的选修课。我理想中寻找的是这样的东西:
List<TSRCategory> electives = new List<TSRCategory>();
foreach (var i in client.Electives.Split('&'))
{
int id = Int32.Parse(i);
electives.Add(db.TSRCategories.Find(id));
}
TSRCategories = electives.Include("Competencies.CompetencySkills").ToList();
当然,无论出于何种原因,这都无法完成(关于为什么无法完成,我实际上不知道该在网上搜索什么!)。 Electives 是一个以 & 作为分隔符的字符串,用于将 ID 分隔到一个数组中。 TSRCategories 包含 Competencies,Competencies 包含 CompetencySkills。有没有一种方法可以在几行代码中有效地做到这一点?
using System.Data.Entity;
from x in db.Z.Include(x => x.Competencies)
.Include(x => x.Competencies.CompetencySkills)
select a.b.c;
按给定的 ID 列表搜索:
int[] ids = new int[0]; // or List<int>
from x in db.Z
where ids.Contains(x.Id)
select a.b.c;
你会发现,将关联的id一个一个地取出来,查询性能会很差。您可以通过首先投影所有需要的 id 的列表来一次性获取它们(我在这里假定了键名 ElectiveId
):
var electiveIds = client.Electives.Split('&')
.Select(i => Int32.Parse(i))
.ToArray();
var electives = db.TSRCategories
.Include(t => t.Competencies.Select(c => c.CompetencySkills))
.Where(tsr => electiveIds.Contains(tsr.ElectiveId))
.ToList();
但要提到的一件事是,将 ids
存储在由定界符连接的单个字符串字段中违反了数据库规范化。相反,您应该创建一个新的联结点 table,例如ClientElectives
其中 link 以规范化方式与客户关联的选修课 (ClientId, ElectiveId)
。这也将简化您的 EF 检索代码。
编辑
根据 documentation 中的示例,我应该使用 .Select
来指定预先加载的深度(而不是 .SelectMany
或其他扩展方法)。