简体   繁体   中英

Is there anyway in EF Core to Filter Navigation single Property ( not collection )

I have a scenario where I want to fetch navigation property with EF based on a specific condition.

  • Want to fetch Account if its isActive=true otherwise not fetch Account.
  • Want to send isActive=true then share true records; isActive=false the share false records.

Is it possible with EF Core?

Below is the snippet.

 return await _context.Contacts
.Include(x => x.PrefixTitle)
.Include(x => x.Account) // **here i want to fetch this if Account.IsActive=true**
.Include(x => x.AssignedToUser)
.Include(x=>x.LeadSource)
.Include(x=>x.EmailAddress.Where(p=>p.IsDeleted==false))                
.Where(a => a.ContactId == id && a.IsDeleted == false)
.FirstOrDefaultAsync();

Account in above is Single Navigation Property not the collection, below are Contact and Account Classes for details.

public class Contact
{
public int ContactId { get; set; }
public string Department { get; set; }
public int? AccountId { get; set; }
public Account Account { get; set; } //one-many relation
}

public class Account 
{
public int AccountId { get; set; }
public string Name { get; set; }
public ICollection<Contact> Contacts { get; set; } = new List<Contact>(); // One-Many relation
}

any help will be appreciated. Thanks

No easy way.

Project Contact to an anonymous result and conditionally retrieve the Account. EF will automatically fix up references between Contact and retrieved Account.

Then select the Contact from that anonymous result:

 var projected = await _context.Contacts
.Include(x => x.PrefixTitle)
// Don't include it here.  Conditionally add it during projection below.
// .Include(x => x.Account) // **here i want to fetch this if Account.IsActive=true**
.Include(x => x.AssignedToUser)
.Include(x=>x.LeadSource)
.Include(x=>x.EmailAddress.Where(p=>p.IsDeleted==false))                
.Where(a => a.ContactId == id && a.IsDeleted == false)
.Select(c => new {
    c,
    // Only retrieve linked account if it is active
    Account = c.Account.IsActive ? c.Account : null
})
.ToListAsync();

// Finally, select the contact from the projection
return projected.Select(c => c.c).FirstOrDefault(); 

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