【问题标题】:Linq nested select new not workingLinq嵌套选择新不起作用
【发布时间】:2009-11-18 10:31:28
【问题描述】:

我正在尝试使用 Subsonic 进行预加载,但它一直为我返回 null。

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

我在这里错过了什么。任何帮助将不胜感激。

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();

}

更新(09 年 8 月 11 日):

更多地玩弄代码,我发现在以下示例中设置 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(不是因为这个问题)。

【问题讨论】:

  • 根据这个帖子,投影存在问题(选择非 SubSonic 类型):groups.google.com/group/subsonicproject/browse_thread/thread/… 可能与此有关。
  • 您使用的是哪个亚音速版本?
  • @Funky812:亚音速版本 3.0.0.3
  • 我也遇到过同样的问题,尝试了 Funky81 的 fork,但最终还是遇到了投影问题。您对使用 fork 中的代码进行设置有什么建议吗?
  • 又玩弄了一些,最终将所有内容、嵌套模型数据和所有内容返回到一个匿名对象中,然后将其复制到真实对象中。

标签: linq subsonic subsonic3


【解决方案1】:

“UserModel.Company 始终为空。”

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

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

至于风格,我喜欢查询理解语法(“from x in y select”),但在与传统的点符号语法结合使用时会觉得很尴尬。只是很难阅读。 (LINQ - Fluent and Query Expression - Is there any benefit(s) of one over other?)。

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

另外,由于查询已经返回IEnumerable&lt;T&gt;,并且调用ToList() 会强制实现所有项目,因此如果可能,我将修改我的方法以返回IEnumerable&lt;T&gt;

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

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));

【讨论】:

  • Jay,我实施了您的建议,现在我收到了 Subsonic 错误:“引用未定义的列”。我会继续排查问题。
【解决方案2】:

两件事

  1. 当您的方法的签名行显示 IList&lt;User&gt; 时,您返回的是 List&lt;UserModel&gt;UserModel 是否继承自 User

  2. 我错过了什么,e 来自哪里?

名字 = e.名字, 姓氏 = e.姓氏, BirthDate = e.BirthDate Blockquote

【讨论】:

  • wawa,关于 1) 我的错,返回签名应该是 IList。我将更新原始问题中的代码 2) 同样,我的错误,e,应该是你。我所做的是我复制了实际的源代码并将其变成了我可以分享的东西。但它似乎做得不够仔细。感谢收看。
【解决方案3】:

请查看我的 fork @ github (http://github.com/funky81/SubSonic-3.0/commit/aa7a9c1b564b2667db7fbd41e09ab72f5d58dcdb) 以获得此解决方案,实际上当 subsonic 尝试投影新类型类时出现问题,因此您的代码实际上没有任何问题:D

【讨论】:

    猜你喜欢
    • 2018-08-10
    • 1970-01-01
    • 2017-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-10
    • 2019-10-04
    相关资源
    最近更新 更多