У нас есть несколько классов с несколькими отношениями 1: 1 для быстрых объединений, и хотя это хорошо работает для анонимных типов для табличного отображения, я не уверен, как полностью заполнить тип в одном запросе linq.
У нас есть эти свойства, потому что они отключены 1: 1, или мы не хотим запрашивать через дочернюю коллекцию, чтобы найти «первичное» каждое отображение, вместо этого мы берем на себя затраты, устанавливая эти Первичные идентификаторы при сохранении.
Урезанный пример для контекста этого поста:
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; }
}
Проблема в том, что при отображении списка контактов, PrimaryAddress
и PrimaryEmail
должны быть загружены с отложенной загрузкой. Если мы сделаем DataLoadOptions
, это также не даст желаемого эффекта, так как это 1: 1, пример:
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();
Приведенный выше код приводит к INNER JOIN , так как он обрабатывает его как родительское отношение, он не учитывает обнуляемое отношение FK и присоединяется слева к свойствам 1: 1. Желаемый запрос будет выглядеть примерно так:
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
Есть ли способ сделать это и получить IQueryable с этими обнуляемыми свойствами 1: 1 или даже списком? Из-за других ограничений нам нужно, чтобы тип был Contact
, поэтому анонимные типы не будут работать. Довольно открытый для опций, все будет лучше, чем ленивая загрузка n * (количество 1: 1) +1 запросов на количество отображаемых строк.