我想在使用INCLUDE语句时只从EF中的查询中获取特定列,而不是返回所有列。
此外,如果我还希望从我的Customers对象中恢复较短的结果集,该怎么办呢?
有办法吗?
这是我的问题:
void Main()
{
IEnumerable<Customer> customerProjectsList = GetCustomerProjects();
customerProjectsList.Dump();
}
public List<Customer> GetCustomerProjects()
{
try
{
using (YeagerTech DbContext = new YeagerTech())
{
var customer = DbContext.Customers.Include("Projects");
return customer;
}
}
catch (Exception ex)
{
throw ex;
}
}
我一直在尝试使用以下查询,但得到的错误是&#34;无法隐式转换类型&#39; System.Linq.IQueryable&#39;到&#39; System.Collections.Generic.ICollection&#39;。存在显式转换(您是否错过了演员?)&#34;
以下是查询: void Main() { 列出customerProjectsList = GetCustomerProjects(); customerProjectsList.Dump(); }
public List<CustomerDTO> GetCustomerProjects()
{
try
{
using (YeagerTech DbContext = new YeagerTech())
{
var customerlist = DbContext.Customers.Select(s =>
new CustomerDTO()
{
CustomerID = s.CustomerID,
Projects =
from p in Projects
where p.CustomerID == s.CustomerID && p.Quote != null
select new Project { Description = p.Description, Quote = p.Quote }
}).ToList<Project>();
return customerlist.ToList();
}
}
catch (Exception ex)
{
throw ex;
}
}
如果我在LINQPad中将此相同的查询作为C#语句而不是C#程序运行,则查询结果可以正常生成。
我只是想通过这种简单的方式尝试使用特定的列来获取分级列表。
var result = (from c in Customers
select new
{
c.CustomerID,
Projects =
from p in Projects
where p.CustomerID == c.CustomerID && p.Quote != null
select new { p.Description, p.Quote }
});
result.Dump();
答案 0 :(得分:1)
你不一定需要包括;如果您在Customers
和Projects
之间有导航属性,则可以投影到新对象:
var customers = (from c in DbContext.Customers
select new
{
FirstName = c.FirstName,
ProjectName = c.Project.Name
}).ToList().Select(x => new Customer
{
FirstName = x.FirstName,
Project = new Project()
{
Name = x.ProjectName
}
}).ToList();
这将返回Customers
的列表,其中仅填充名字,每个客户将包含填充了名称的Project
属性。这非常适合性能,因为EF向您的数据库发送的查询将很短并且将快速返回结果集。
修改强>:
考虑到Projects
是ICollection
,我认为最可维持的做法是创建几个DTOs:
public CustomerDTO
{
public int CustomerId;
public List<ProjectDTO> projects;
}
public ProjectDTO
{
public string Description;
public string Quote;
}
并向他们投射如下:
var qry = (from c in context.Customers
select new CustomerDTO()
{
CustomerId = c.CustomerId,
Projects = (from pr in context.Projects
where c.ProjectId equals pr.Id
select new ProjectDTO
{
Description = pr.Description,
Quote = pr.Quote
}).ToList()
});
答案 1 :(得分:0)
您必须使用投影来限制检索的列。很多投影的例子都可以在互联网上找到,例如:
DateTime twoDaysAgo = DateTime.Now.AddDays(-2);
var groupSummaries = _recipeContext.Groups.OrderBy(g => g.Name)
.Select(g => new GroupSummaryModel{
Id = g.Id,
Name = g.Name,
Description = g.Description,
NumberOfUsers = g.Users.Count(),
NumberOfNewRecipes = g.Recipes.Count(r => r.PostedOn > twoDaysAgo)
});
关键是如果需要多次使用新机制。这里它与新的GroupSummaryModel一起使用。
修改
var qry = (from c in context.Customers
select new CustomerDTO()
{
CustomerId = c.CustomerId,
Projects = (from pr in context.Projects
where c.ProjectId equals pr.Id
select new ProjectDTO
{
Description = pr.Description,
Quote = pr.Quote
}) //--> no tolist here
}).ToList(); //--> only here