Linq嵌套选择新的不工作

时间:2009-08-10 19:53:57

标签: linq subsonic subsonic3

我正在尝试使用Subsonic进行急切加载,并且它一直在为我返回null。

在下面的方法中,我试图给包含另一个域模型(CompanyModel)的域模型(UserModel)进行水合。但是,使用下面的代码,UserModel.Company始终为null。

我在这里缺少什么。任何帮助将不胜感激。

public IList<UserModel> GetUsers()
{             
    return (from u in SubsonicSqlServer.Users.All()
            select new UserModel
                       {
                           UserId= u.UserId,
                           Company = (from c in u.Companies
                                    select new CompanyModel
                                               {
                                                   CompanyId = c.CompanyId,
                                                   CompanyName = c.CompanyName
                                               }).SingleOrDefault(),
                           FirstName = u.FirstName,
                           LastName = u.LastName,
                           BirthDate = u.BirthDate
                       }).ToList();

}

更新(08/11/09):

更多关注代码,我发现在以下示例中设置CompanyId也不起作用。我最初认为这是Subsonic的问题,但如果下面的代码不起作用,我猜它与我的Linq语句有关。有什么想法吗?

public IList<UserModel> GetUsers()
{             
    return (from u in SubsonicSqlServer.Users.All()
            select new UserModel
                       {
                           UserId= u.UserId,                            
                           CompanyId = Guid.NewGuid(),
                           FirstName = u.FirstName,
                           LastName = u.LastName,
                           BirthDate = u.BirthDate
                       }).ToList();

}

更新(2009年11月17日):

还没有找到解决方案。但我们正在转向nHibernate(不是因为这个问题)。

3 个答案:

答案 0 :(得分:2)

“UserModel.Company始终为null。”

因为你用一个以.SingleOrDefault()结尾的表达式来设置它,所以我建议查询不返回单个项目。开始在那里调查。如果您期望u.Companies中只有一个项目,请更改为.Single()并强制提前失败。

我认为您可以在创建新的.Single()对象之前执行CompanyModel

至于样式,我喜欢查询理解语法(“from x in y select”),但在与传统的点符号语法结合时发现它很尴尬。这很难读懂。 (LINQ - Fluent and Query Expression - Is there any benefit(s) of one over other?)。

考虑在查询理解中使用let以使其更清晰。

此外,由于查询已经返回IEnumerable<T>,并且调用ToList()强制要实现所有项目,我会修改我的方法以便在可能的情况下返回IEnumerable<T>

所以,在你的情况下,我会重构第一个说:

public IEnumerable<User> GetUsers()
{ 
    return from u in SubsonicSqlServer.Users.All()
        let c = u.Companies.Single()
        select new UserModel
        {
            UserId = u.UserId,
            Company = new CompanyModel
            {
                CompanyId = c.CompanyId,
                CompanyName = c.CompanyName
            },
            FirstName = e.FirstName,
            LastName = e.LastName,
            BirthDate = e.BirthDate
        };
}

如果在对象模型中有意义,可以修改User以使构造函数采用任何类型u,并且它变得更简单:

return from u in SubsonicSqlServer.Users.All()
    select new UserModel (u);

甚至

return SubsonicSqlServer.Users.All().Select(u => new UserModel (u));

答案 1 :(得分:0)

两件事

  1. 当您的方法的签名行显示List<UserModel> IList<User> UserModel继承自User时,您返回e

  2. 我错过了什么,{{1}}来自哪里?

  3.   

    FirstName = e.FirstName,   LastName = e.LastName,   BirthDate = e.BirthDate Blockquote

答案 2 :(得分:0)

请查看我的fork @ github(http://github.com/funky81/SubSonic-3.0/commit/aa7a9c1b564b2667db7fbd41e09ab72f5d58dcdb)这个解决方案,实际上当亚音速尝试投影新类型时会出现问题,所以实际上你的代码没有错:D