We have several classes with multiple 1:1 Relationships for quick joins, and while this works fine for anonymous types for tabular display, I'm unsure how to fully populate the type in a single linq query.
We have these properties either because it's an off 1:1, or we don't want to query through a child collection to find a "primary" every display, we instead incur the cost by setting these Primary IDs on save.
A stripped down example for the context of this post:
public class Contact
{
public long Id { get; set; }
public EntitySet<Address> Addresses { get; set; }
public EntityRef<Address> PrimaryAddress { get; set; }
public long? PrimaryAddressId { get; set; }
public EntitySet<Email> Emails { get; set; }
public EntityRef<Email> PrimaryEmail { get; set; }
public long? PrimaryEmailId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Address
{
public long Id { get; set; }
public EntitySet<Contact> Contacts { get; set; }
public bool IsPrimary { get; set; }
public string Street1 { get; set; }
public string Street2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Country { get; set; }
}
public class Email
{
public long Id { get; set; }
public EntitySet<Contact> Contacts { get; set; }
public bool IsPrimary { get; set; }
public string Address { get; set; }
}
The problem is when displaying a list of contacts, the PrimaryAddress
and PrimaryEmail
have to be lazy loaded. If we do DataLoadOptions
it doesn't give the desired effect either since it's a 1:1, example:
var DB = new DataContext();
var dlo = new DataLoadOptions();
dlo.LoadWith<Contact>(c => c.PrimaryAddress);
dlo.LoadWith<Contact>(c => c.PrimaryEmail);
DB.LoadOptions = dlo;
var result = from c in DB.Contacts select c;
result.ToList();
The above code results in a INNER JOIN since it treats it like a parent relationship, it doesn't respect the nullable FK relationship and left join the 1:1 properties. The desired query would be something like:
Select t1.*, t.2*, t3.*
From Contact t1
Left Join Address t2 On t1.PrimayAddressId = t2.Id
Left Join Email On t1.PrimaryEmailId = t3.Id
Is there a way to do this and get a IQueryable with these nullable 1:1 properties populated, or even a List? Due to other constraints, we need the type to be Contact
, so anonymous types won't work. Pretty open to options, anything would be better than lazy loading n*(number of 1:1s)+1 queries for the number of rows we display.