LINQ to SQL奇怪加入问题

时间:2008-11-21 12:31:15

标签: c# linq-to-sql inner-join

我有一个包含两个表的简单数据库。用户和配置。用户具有将其链接到特定配置的外键。

我遇到一个奇怪的问题,无论第二个参数值如何,以下查询总是会导致内部连接到Configuration表。据我所知,即使对象初始化的“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();
    }
}

提前致谢,

马丁。

3 个答案:

答案 0 :(得分:0)

我认为它不会那样。

我建议将其拆分为2个不同的查询。

可能有更好的方法,但需要更多的“探测”。

答案 1 :(得分:0)

不,这不行。我多次遇到过类似的问题。其原因与编译时的表达式与运行时的条件有关。

您可以执行2次查询,或者如果您不介意加入配置而不管loadConfiguration参数如何,您可以使用:

var q = (from c in database.Users
                where c.Username == username
                select c).Single();

然后在结果上使用Linq-to-Objects。

答案 2 :(得分:0)

用SingleOrDefault()替换.Single(),Linq将切换到左外连接。我不知道在你的情况下是否会这样做,但在某些情况下确实如此。

编辑dint看到Single是整个查询而不是配置部分:

试试这个:

     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