简体   繁体   English

实体框架:急切的加载不适用于字符串外键

[英]Entity Framework : Eager loading not working with string foreign key

I am having trouble loading a child entity using eager loading, the eager loading works fine everywhere else in the project but its not working with any of the string foreign keys. 我在使用紧急加载来加载子实体时遇到了麻烦,该紧急加载在项目中的其他任何地方都可以正常工作,但是不能与任何字符串外键一起使用。 My model is : 我的模型是:

public class Listing : BaseAudit<int>
{
    public int? CommunityId { get; set; }
    public string LotId { get; set; }


    public Lot Lot { get; set; }
}

public class Lot : BaseAudit<string>
{
    public ICollection<Listing> Listings { get; set; }
}

public class BaseAudit<T> : BaseId<T>
{
    public BaseAudit()
    {
        CreatedDate = DateTime.Now;
    }

    public DateTime? CreatedDate { get; set; }
    public string CreatedBy { get; set; }
    public DateTime? UpdatedDate { get; set; }
    public string UpdatedBy { get; set; }
}

public class BaseModel
{
    public BaseModel()
    {
        Active = true;
    }

    public bool Active { get; set; }
}

public class BaseId<T> : BaseModel
{
    public T Id { get; set; }
}

I am trying to load Lot property of Listing I have tried: 我正在尝试加载我尝试过的Listing Lot属性:

_db.Listings.Where(m => m.CommunityId == communityId && m.LotId != null).Include(a => a.Lot).ToList();

I have checked that it is generating correct SQL by using a break point but It is always returning with all Lot properties null. 我已经检查过它通过使用断点来生成正确的SQL,但它总是返回所有Lot属性为null。 I can not figure out what am I doing wrong here. 我无法弄清楚我在做什么错。

Short answer: Listings should be a virtual collection; 简短的答案: Listings应该是一个虚拟集合; LotId is never null, and Include should be immediately after your DbSet. LotId永远不会为null,并且Include应该紧接在DbSet之后。 And you should probably model your inheritance strategy 您可能应该为继承策略建模

Long answer It seems you tried to configure a one-to-many relationship between Lots and Listings : Every Lot has zero or more Listings and every Listing belongs to exactly one Lot . 长答案似乎您尝试在LotsListings之间配置一对多关系:每个Lot具有零个或多个Listings ,每个Listing恰好属于一个Lot

For a proper one-to-many you should declare your collection of Listings virtual 对于一对多的人,您应该声明您的清单虚拟清单

public virtual ICollection<Listing> Listings { get; set; }

Because of the one-to-many relation, there is no Listing without a Lot Therefore the foreign key to Lot's primary key LotId is never null. 由于一对多关系,没有Lot就没有Listing ,因此,批次的主键LotId的外键永远不会为空。

So you have a nullable int communityId (is that true? or is communityId an int?), and you want all Listings that have the same value for Listing.CommunityId inclusive the one and only Lot this Listing` has: 所以,你有一个可空INT communityId (这是真的,或者communityId一个int?),并且希望所有Listings具有相同的价值Listing.CommunityId inclusive the one and only地段this Listing`有:

using System.Data.Entity;

List<Listing> result = dbContext.Listings
    .Include(listing => listing.Lot)
    .Where(listing => listing.communityId == communityId)
    .ToList();

If this doesn't help, then your use of inheritance might cause the problems. 如果这样做没有帮助,则您对继承的使用可能会引起问题。 Relational databases don't know the concept of inheritance. 关系数据库不知道继承的概念。 You should tell entity framework using fluent API (or attributes) which inheritance strategy to model into tables. 您应该使用流利的API(或属性)告诉实体框架将哪种继承策略建模到表中。 See Inheritance Strategies 请参阅继承策略

Finally I see that some primary keys are int, and some primary keys are strings. 最后,我看到一些主键是int,一些主键是字符串。 Is that really intended? 那是真的吗? Is it useful? 它有用吗?

EF6 does not support Include with Where on related entities. EF6不支持在相关实体上的“ IncludeWhere ”。

A possible workaround: Entity Framework: Filtering Related Entity Collections 可能的解决方法: 实体框架:筛选相关的实体集合

As of Entity Framework 6, there isn't a way to filter which related entities are loaded when using .Include(). 从Entity Framework 6开始,没有一种方法可以过滤使用.Include()时加载了哪些相关实体。

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

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