EntityFramework:无法在LINQ连接查询

时间:2016-02-11 17:37:30

标签: c# entity-framework linq linq-to-entities

我试图执行涉及嵌套成员的LINQ to Entity查询。以下是实体架构。为简洁起见,我将代码保持在最低限度。

public class NAVSummary
{
    public virtual IList<NAVStatus> Statuses { get; set; }
}

public class NAVStatus
{
    [Key]
    [Column(Order = 0), ForeignKey("NAVSummary")]
    public string Portfolio { get; set; }
    [Key]
    [Column(Order = 1), ForeignKey("NAVSummary")]
    public DateTime ValueDate { get; set; }
    [Key, Column(Order = 3)]
    public int StatusId { get; set; }
    [JsonIgnore]
    public virtual NAVSummary NAVSummary { get; set; }
    [ForeignKey("StatusId")]
    public NAVStatusMaster StatusMaster { get; set; }
}

[Table("NAVRec_StatusMaster")]
public class NAVStatusMaster
{
    [Key]
    public int Id { get; set; }
    public string Description { get; set; }
}

DbContext对所有上述实体都有DbSet。

我有以下LINQ查询:

var navSummariesTemp = dbContext.NAVSummaries
                            .Include(n => n.Statuses)
                            .Include(n => n.Comments)
                            .Include(n => n.Statuses.Select(s => s.StatusMaster))
                            .Include(n => n.Extracts)

                            .Join(dbContext.NAVSummaries,
                            current => new
                            {
                                current.Portfolio,
                                PD = SqlFunctions.DatePart("dw", current.ValueDate) == 2 ? DbFunctions.AddDays(current.ValueDate, -3).Value :
                                        SqlFunctions.DatePart("dw", current.ValueDate) == 1 ? DbFunctions.AddDays(current.ValueDate, -2).Value :
                                                                                            DbFunctions.AddDays(current.ValueDate, -1).Value
                            },
                            previous => new { previous.Portfolio, PD = previous.ValueDate },
                                                (outer, inner) => new { outer, inner })
                            .Where(w => w.outer.Statuses.Count > 0)
                            .Select(s => new
                            {
                                DayOverDayChange = s.outer.DifferencePercent - s.inner.DifferencePercent,
                                IsChange = s.inner.DifferencePercent == s.outer.DifferencePercent ? false : true,
                                Statuses = s.outer.Statuses
                            }).Take(10).ToList();

上述查询产生除NAVStatus.StatusMaster属性之外的所有内容。虽然我已使用Include()扩展名在查询开头包含了该属性,但 public NAVStatusMaster StatusMaster {get;组; 仍然 null

但是,当我执行以下查询时,StatusMaster字段确实从数据库记录中设置。

var statusResult = dbContext.NAVSummaries
                    .Include(n => n.Statuses)
                    .Include(n => n.Comments)
                    .Include(n => n.Statuses.Select(s => s.StatusMaster))
                    .Include(n => n.Extracts)
                    .Where(n => n.Statuses.Count > 0).First();

真的很感激,如果有人可以帮我解决这个问题。

1 个答案:

答案 0 :(得分:0)

预先加载仅适用于查询的最后部分。如果你在包含后使用投影,一切都会默默地丢失。解决问题的唯一方法是专门将StatusMaster放入投影中:

.Select(s => new
{
   DayOverDayChange = s.outer.DifferencePercent - s.inner.DifferencePercent,
   IsChange = s.inner.DifferencePercent == s.outer.DifferencePercent ? false : true,
   Statuses = s.outer.Statuses,
   Statusmaster = s.outer.Statuses.SelectMany(s => s.StatusMaster)
                        }).Take(10).ToList();

但是我认为你真的不希望StatusMaster成为一个单独的列表。也许在select:

中最终可以使用include
.Select(s => new
{
   DayOverDayChange = s.outer.DifferencePercent - s.inner.DifferencePercent,
   IsChange = s.inner.DifferencePercent == s.outer.DifferencePercent ? false : true,
   Statuses = s.outer.Statuses.Include(s => s.StatusMaster),
                        }).Take(10).ToList();

我不确定这会工作但不能测试它,因为我必须去某个地方:)在我看来最好的选择就是让StatusMaster虚拟来启用延迟加载。

See this link