Вопрос

У меня есть простая база данных с двумя таблицами.Пользователи и конфигурации.У пользователя есть внешний ключ, чтобы связать его с определенной конфигурацией.

У меня возникла странная проблема, когда следующий запрос всегда вызывает внутреннее соединение с таблицей конфигурации независимо от значения второго параметра.Насколько я могу судить, даже несмотря на то, что часть инициализации объекта "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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top