使用EF从INCLUDE语句中获取特定列

时间:2015-04-05 16:39:21

标签: c# linq entity-framework

我想在使用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();

2 个答案:

答案 0 :(得分:1)

你不一定需要包括;如果您在CustomersProjects之间有导航属性,则可以投影到新对象:

  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向您的数据库发送的查询将很短并且将快速返回结果集。

修改

考虑到ProjectsICollection,我认为最可维持的做法是创建几个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)
    });

我从这里拿走了它: http://www.davepaquette.com/archive/2013/02/09/writing-efficient-queries-with-entity-framework-code-first-part-2.aspx

关键是如果需要多次使用新机制。这里它与新的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