简体   繁体   English

LINQ To SQL奇怪的联接问题

[英]LINQ To SQL Weird Join Issue

I have a simple database with two tables. 我有一个带有两个表的简单数据库。 Users and Configurations. 用户和配置。 A user has a foreign key to link it to a particular configuration. 用户具有外键以将其链接到特定配置。

I am having a strange problem where the following query always causes an inner join to the Configuration table regardless of the second parameter value. 我遇到一个奇怪的问题,即无论第二个参数值如何,以下查询总是会导致内部联接到配置表。 As far as I can tell, even though the "UserConfiguration =" part of the object initialisation is conditional, LINQ doesn't see that and determines that a relationship is followed in any case. 据我所知,即使对象初始化的“ UserConfiguration =”部分是有条件的,LINQ也不会看到并确定在任何情况下都遵循关系。

If I actually remove that last initialisation, the whole thing works as expected. 如果我实际上删除了最后一个初始化,则整个过程将按预期工作。 It doesn't inner join when loadConfiguration == false and it does join when loadConfiguration == true. 当loadConfiguration == false时,它不进行内部联接;当loadConfiguration == true时,它进行内部联接。

Anyone got any ideas about this? 有人对此有任何想法吗? Is this syntax just not going to work? 这种语法是否行不通? The only thought I have now is to wrap the return in a basic if statement - I just wanted to avoid the duplicated lines. 我现在唯一的想法是将返回值包装在基本的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();
    }
}

Thanks in advance, 提前致谢,

Martin. 马丁

I dont think it will work like that. 我不认为它会那样工作。

I suggest splitting it into 2 distinct queries. 我建议将其分为2个不同的查询。

There are probably better ways, but it would require more 'plumbling'. 也许有更好的方法,但是这需要更多的“麻烦”。

Nope, this will not work. 不,这是行不通的。 I've run into similar issues many times. 我已经多次遇到类似的问题。 The reason for that has to do with expressions at compile time vs. conditions at run-time. 这样做的原因与编译时的表达式与运行时的条件有关。

You could do 2 queries or if you don't mind joining to configuration regardless of loadConfiguration parameter, you could use: 您可以执行2个查询,或者如果不考虑加入配置而不考虑loadConfiguration参数,则可以使用:

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

and then use Linq-to-Objects on the result. 然后在结果上使用Linq-to-Objects。

Replace .Single() with SingleOrDefault() and Linq will switch to a left outer join. 用SingleOrDefault()替换.Single(),Linq将切换到左外部联接。 I don't know if in your case it will do it, but in some cases it does. 我不知道您是否会这样做,但在某些情况下会这样做。

Edit dint's see the Single was for the entire query and not for the configuration part: 编辑dint看到Single适用于整个查询,而不适用于配置部分:

try this: 尝试这个:

     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 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM