简体   繁体   中英

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:

_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. I can not figure out what am I doing wrong here.

Short answer: Listings should be a virtual collection; LotId is never null, and Include should be immediately after your 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 .

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.

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:

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. See Inheritance Strategies

Finally I see that some primary keys are int, and some primary keys are strings. Is that really intended? Is it useful?

EF6 does not support Include with Where on related entities.

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().

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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