简体   繁体   English

EF 6添加包含导航属性的子句

[英]EF 6 Add Where Clause To An Include With Navigation Property

I'm going to try ask this question without posting all the objects in my model. 我将尝试在不发布模型中的所有对象的情况下提出这个问题。 I have a somewhat complex query but only two objects are related to the problem. 我有一个有点复杂的查询,但只有两个对象与问题有关。

I have a website used to run office football pools. 我有一个用来办公室足球池的网站。 So my domain model has Team and TeamRecords 所以我的域模型有Team和TeamRecords

Here are the definitions. 这是定义。 I removed some irrelevant properties on the object. 我删除了对象上的一些不相关的属性。

public class Team
{
    /// <summary>
    /// Team ID
    /// </summary>
    public int TeamID { get; set; }


    /// <summary>
    /// Team Recordproperty
    /// </summary>
    public virtual ICollection<TeamRecord> TeamRecords { get; set; }
}

public class TeamRecord
{

    /// <summary>
    /// Team ID
    /// </summary>
    public int TeamID { get; set; }

    /// <summary>
    /// Team the record belongs to
    /// </summary>
    public virtual Team Team { get; set;}

    /// <summary>
    /// Season ID
    /// </summary>
    public int SeasonID { get; set; }

    /// <summary>
    /// Season navigation property
    /// </summary>
    public virtual Season Season { get; set; }

}

I configure the Team to TeamRecords relationship like this: 我将Team配置为TeamRecords关系,如下所示:

HasMany(t => t.TeamRecords).WithRequired(tr => tr.Team).HasForeignKey(tr=>new {tr.TeamID});

Then I try to run a query like this. 然后我尝试运行这样的查询。 Basically when I select a team, I want to only select the teamrecord for the current season. 基本上当我选择一支球队时,我只想选择本赛季的球队记录。 So I want to add a where clause to my Include method. 所以我想在我的Include方法中添加一个where子句。 Ignore the other objects in the query. 忽略查询中的其他对象。 They're probably self explanatory. 他们可能是自我解释的。

var picks = context.Picks.Where(p => ((p.Game.SeasonID == seasonID) && (p.Game.Week ==     week) && (p.PoolID == poolID) && (p.UserID == userID)))
                            .Include(p => p.Game).Include(p => p.Game.HomeTeam).Include(p => p.Game.VisitingTeam).Include(p => p.Pool)
                            .Include(p => p.Game.HomeTeam.TeamRecords.Where(tr=>tr.SeasonID == seasonID))
                            .Include(p => p.Game.VisitingTeam.TeamRecords.Where(tr=>tr.SeasonID == seasonID))
                            .Select(p => p);

When I execute that line of code, I get the following error 当我执行该行代码时,我收到以下错误

The Include path expression must refer to a navigation property defined on the type. Include路径表达式必须引用在类型上定义的导航属性。 Use dotted paths for reference navigation properties and the Select operator for collection navigation properties. 使用虚线路径作为参考导航属性,使用Select运算符作为集合导航属性。

How can I accomplish this type of filtering? 我怎样才能完成这种过滤? I've searched the internet and have not had any luck. 我在网上搜索过,没有运气。

You can change it to a select statement that produces anonymous type, then execute the query and select the root object again. 您可以将其更改为生成匿名类型的select语句,然后执行查询并再次选择根对象。

You can try something like this. 你可以尝试这样的事情。

var picks = context.Picks.Where(p => ((p.Game.SeasonID == seasonID) && (p.Game.Week == week) && (p.PoolID == poolID) && (p.UserID == userID)))
    .Select(p => new
    {
        Pick = p,
        Game = p.Game,
        HomeTeam = p.Game.HomeTeam,
        VisitingTeam = p.Game.VisitingTeam,
        HomeTeamRecords = p.Game.HomeTeam.TeamRecords.Where(tr => tr.SeasonID == seasonID),
        VisitingTeamRecords = p.Game.VisitingTeam.TeamRecords.Where(tr => tr.SeasonID == seasonID),
        Pool = p.Pool
    })
    .ToArray().Select(p => p.Pick).ToArray();

And they will automatically connected, Pick to Game , Game to HomeTeam , Game to VisitingTeam , HomeTeam to TeamRecords , VisitingTeam to TeamRecords , Pick to Pool . 他们将自动连接, Pick GameGameHomeTeamGameVisitingTeamHomeTeamTeamRecordsVisitingTeamTeamRecordsPick to Pool

Also known as relationship fix-up . 也被称为关系修复

Entity Framework has no direct support for filtering the Include extension method . 实体框架没有直接支持过滤Include扩展方法

A common alternative is to combine the Query and Load methods on a tracked entity to perform a filtered explicit load . 常见的替代方法是在跟踪的实体上组合QueryLoad方法以执行过滤的显式加载 (Search for Applying filters when explicitly loading related entities on that linked article.) (在该链接文章上明确加载相关实体时搜索应用过滤器 。)

Taking just your Team and TeamRecords entities, this would look something like this: 仅使用您的TeamTeamRecords实体,这看起来像这样:

// Ensure lazy loading is turned off
context.Configuration.LazyLoadingEnabled = false;

// load the team
var team = context.Teams.Find(teamId);

// explicitly load the team records for the current season
context.Entry(team)
    .Collection(t => t.TeamRecords)
    .Query()
    .Where(r => r.SeasonId == currentSeasonId)
    .Load();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM