在将include语句与实体框架一起使用时选择特定列

sag*_*y36 14 c# entity-framework

当我需要一个层级(父子)关系时,我通常在我的EF查询中使用Include语句.

例:

DbContext.Customers.Include("Projects");
Run Code Online (Sandbox Code Playgroud)

这很好,但Customers和Projects实体总是带回所有列.

我知道下面的查询将带回父表中的特定列,但我也试图只返回子表中的特定列.如果我在Projects上使用intellisense,它显然是一个集合,并没有给出特定的属性来选择.

from c in Customers
let Projects = c.Projects.Where (p => p.Notes != null)
where Projects.Any()
select new
{
    c.UserName,
    Projects
}
Run Code Online (Sandbox Code Playgroud)

我试着炼查询到下面的代码,但你可以看到,该项目的实体是一个孩子的客户的实体,因此,没有一个特定的列在查询中进行选择.它显然是一个集合.

在查询中使用Include时,是否有办法在每个实体中仅返回特定列

请注意,我的YeagerTechDB.ViewModels.Customers模型由驻留在Customer和Project实体中的所有列组成.

public List<YeagerTechDB.ViewModels.Customers> GetCustomerProjects()
        {
            try
            {
                using (YeagerTech DbContext = new YeagerTech())
                {
                    var customer = DbContext.Customers.Include("Projects").Select(s =>
                        new YeagerTechDB.ViewModels.Customers()
                        {
                            CustomerID = s.CustomerID,
                            ProjectID = s.ProjectID,
                            UserName = s.UserName,
                            Name = s.Projects.,
                        });

                     return customer.ToList();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
Run Code Online (Sandbox Code Playgroud)

对1个儿童实体的答案#1

from c in Customers
let Projects = c.Projects.Where (p => p.Notes != null)
where Projects.Any()
select new
{
    c.UserName,
    Projects
}
Run Code Online (Sandbox Code Playgroud)

对2个儿童实体的答案#2

from c in Customers
let highValueP =
    from p in c.Projects
    where p.Quote != null
    select new { p.ProjectID, p.Name, p.Quote }
where highValueP.Any()
from p in Projects
let highValuet =
    from t in p.TimeTrackings
    where t.Notes != null
    select new { t.ProjectID, t.Notes }
where highValuet.Any()
select new 
{
    c.CustomerID,
    Projects = highValueP,
    TimeTrackings = highValuet
}
Run Code Online (Sandbox Code Playgroud)

编辑#3 在此输入图像描述

Bor*_*lov 15

查看此链接了解更多详情.简而言之,诀窍是使用.Select()和匿名类型来限制所需的列.在下面的示例中,首先Select()实际上是这样做的:

var results = context.Products
        .Include("ProductSubcategory")
        .Where(p => p.Name.Contains(searchTerm)
                    && p.DiscontinuedDate == null)
        .Select(p => new
                        {
                            p.ProductID,
                            ProductSubcategoryName = p.ProductSubcategory.Name,
                            p.Name,
                            p.StandardCost
                        })
        .AsEnumerable()
        .Select(p => new AutoCompleteData
                            {
                                Id = p.ProductID,
                                Text = BuildAutoCompleteText(p.Name,
                                    p.ProductSubcategoryName, p.StandardCost)
                            })
        .ToArray();
Run Code Online (Sandbox Code Playgroud)

  • 如果您包含“Products”的多个子代怎么办?EG 如果您有“ProductSubCategories”而不是“ProductSubcategory”,并且您只想选择每个类别的名称。 (2认同)
  • 这“有效”,但它会导致对每个父项进行查询,而不是进行联接。 (2认同)