实体框架包括

时间:2017-10-23 19:32:40

标签: entity-framework linq asp.net-core

我正在尝试选择所有客户的最新版本,并使用各自付款的最新版本和付款相应的细分名称加载每个对象。

这是一个.net Core 2.0项目。

控制器正在使用:

using System;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using CBFU.Data;
using CBFU.Models;
using Microsoft.EntityFrameworkCore;

创建一个没有外键的客户端。

使用外键创建付款:ClientIdSegmentId

创建没有外键的段。

我在想:

var clients = _context.Clients
    .Where(client => client.IsLatest == 1)
    .Include(client => client.Payments
        .Select(payment => payment.IsLatest == 1)
            .Select(payment => payment.Segment))
    .ToList();

但这不起作用。下面我列举了一些我尝试过的东西以及它是否有效。我没有使用.ThenInclude的示例,因为我的智能感知器没有响应它。

// 1 This works: Loading payments into clients
var clients = _context.Clients
    .Where(client => client.IsLatest == 1)
    .Include(client => client.Payments)
    .ToList();

// 2 This does NOT work: Loading payment with IsLatest == 0 into clients
var clients = _context.Clients
    .Where(client => client.IsLatest == 1)
    .Include(client => client.Payments
        .Select(p => p.IsLatest == 1))
    .ToList();

// 3 This does NOT work: Loading segment into payments into clients
var clients = _context.Clients
    .Where(client => client.IsLatest == 1)
    .Include(client => client.Payments
        .Select(p => p.Segment == 1))
    .ToList();

2和3都给出了相同的错误:

  

属性表达式'client => {来自client.Payments select([payment] .IsLatest == 1)}'中的付款付款无效。表达式应代表属性访问:'t => t.MyProperty'。有关包含相关数据的更多信息,请参阅http://go.microsoft.com/fwlink/?LinkID=746393。   来源=<无法评估异常来源>

我的课程如下:

public class Client
{
    public int Id { get; set; }

    public int IsLatest { get; set; }

    public ICollection<Payment> Payments { get; set; }
}

public class Payment
{
    public int Id { get; set; }

    public Client Client { get; set; }
    [Required]
    [Display(Name = "Client")]
    public int ClientId { get; set; }

    public Segment Segment { get; set; }
    [Required]
    [Display(Name = "Segment")]
    public int SegmentId { get; set; }

    public int IsLatest { get; set; }
}

public class Segment
{
    public int Id { get; set; }
    public string Name { get; set; }
}

1 个答案:

答案 0 :(得分:2)

EF Core之前从未支持过滤的Include,并且EF Core仍然不支持(截至当前版本2.0)。 EF Core 2.0引入了Model-level query filters,但它们适用于所有查询,必须在不需要时专门关闭。也不够灵活,无法处理动态查询级别过滤。

您可以做的是利用所谓的导航属性修正的组合,热切加载和过滤文档的Loading Related Data部分中描述的加载实体技术:

var clientQuery = _context.Clients
    .Where(client => client.IsLatest == 1);

var clients = clientQuery.ToList();

clientQuery
    .SelectMany(c => c.Payments)
    .Include(p => p.Segment)
    .Where(p => p.IsLatest == 1)
    .Load();