Проблема со Странным соединением LINQ С SQL
-
08-07-2019 - |
Вопрос
У меня есть простая база данных с двумя таблицами.Пользователи и конфигурации.У пользователя есть внешний ключ, чтобы связать его с определенной конфигурацией.
У меня возникла странная проблема, когда следующий запрос всегда вызывает внутреннее соединение с таблицей конфигурации независимо от значения второго параметра.Насколько я могу судить, даже несмотря на то, что часть инициализации объекта "UserConfiguration =" является условной, LINQ этого не видит и определяет, что связь соблюдается в любом случае.
Если я действительно удалю эту последнюю инициализацию, все будет работать так, как ожидалось.Он не выполняет внутреннее объединение, когда loadConfiguration == false, и он выполняет объединение, когда loadConfiguration == true.
У кого-нибудь есть какие-нибудь идеи по этому поводу?Неужели этот синтаксис просто не будет работать?Единственная мысль, которая у меня сейчас есть, - это обернуть возврат в базовую инструкцию if - я просто хотел избежать дублирования строк.
public UserAccount GetByUsername(string username, bool loadConfiguration)
{
using (Database database = new Database())
{
if (loadConfiguration)
{
DataLoadOptions loadOptions = new DataLoadOptions();
loadOptions.LoadWith<User>(c => c.Configuration);
database.LoadOptions = loadOptions;
}
return (from c in database.Users
where c.Username == username
select new UserAccount
{
ID = c.ID,
ConfigurationID = c.ConfigurationID,
Username = c.Username,
Password = c.Password.ToArray(),
HashSalt = c.HashSalt,
FirstName = c.FirstName,
LastName = c.LastName,
EmailAddress = c.EmailAddress,
UserConfiguration = (loadConfiguration) ? new ApplicationConfiguration
{
ID = c.Configuration.ID,
MonthlyAccountPrice = c.Configuration.MonthlyAccountPrice,
TrialAccountDays = c.Configuration.TrialAccountDays,
VAT = c.Configuration.VAT,
DateCreated = c.Configuration.DateCreated
} : null
}).Single();
}
}
Заранее спасибо,
Мартин.
Решение
Я не думаю, что это сработает именно так.
Я предлагаю разделить его на 2 отдельных запроса.
Вероятно, есть способы получше, но это потребовало бы большего "отвеса".
Другие советы
Нет, это не сработает.Я много раз сталкивался с подобными проблемами.Причина этого связана с выражениями во время компиляции по сравнениюусловия во время выполнения.
Вы могли бы выполнить 2 запроса или, если вы не возражаете присоединиться к конфигурации независимо от параметра loadConfiguration, вы могли бы использовать:
var q = (from c in database.Users
where c.Username == username
select c).Single();
а затем используйте Linq-to-Objects для получения результата.
Замените .Single() на SingleOrDefault(), и Linq переключится на левое внешнее соединение.Я не знаю, сработает ли это в вашем случае, но в некоторых случаях это так и есть.
Отредактируйте dint, чтобы увидеть, что сингл был для всего запроса, а не для части конфигурации:
попробуй это:
UserConfiguration = (loadConfiguration && c.Configuration != null) ? new ApplicationConfiguration
{
ID = c.Configuration.ID,
MonthlyAccountPrice = c.Configuration.MonthlyAccountPrice,
TrialAccountDays = c.Configuration.TrialAccountDays,
VAT = c.Configuration.VAT,
DateCreated = c.Configuration.DateCreated
} : null