如何使用linq for sql的工厂类?

And*_*uul 6 factory-method factory-pattern linq-to-sql

我在我的数据库模型之上有一个模型,并在我的存储库中映射对象.

然而,显然我是否直接在我的GetUsers中"选择新"或"选择工厂结果"如下所示.我在运行时得到错误,方法CreateFromDbModel没有转换为sql(System.NotSupportedException).

有没有解决的办法?我能以某种方式修补它吗?

想要使用工厂方法的原因是我可能会在其他地方实例化对象,并希望将"映射代码"保存在一个地方......

感谢任何评论,安德斯

    public IQueryable<User> GetUsers(bool includeTeams)
    {
        return from u in _db.sc_Players
               where (includeTeams || (!u.aspnet_User.sc_Player.IsTeam))
               select UserFactory2.CreateFromDbModel(u);
    }


    public static User CreateFromDbModel(sc_Player player)
    {
        return new User
                   {
                       Id = player.sc_PlayerID,
                       FirstName = player.FirstName.Trim(),
                       LastName = player.LastName.Trim(),
                       PresentationName = player.FirstName.Trim() + " " + player.LastName.Trim(),
                       LoginName = player.aspnet_User.LoweredUserName,
                       IsTeam = player.IsTeam,
                       Email = player.aspnet_User.aspnet_Membership.Email,
                       Password = player.aspnet_User.aspnet_Membership.Password
                   };
    }
Run Code Online (Sandbox Code Playgroud)

Dou*_*las 0

问题是因为您在 GetUsers 方法中返回 IQueryable 吗?尝试返回 List。这将强制 Linq 查询在该方法内执行。

\n\n
public List<User> GetUsers(bool includeTeams)\n{\n    return (from u in _db.sc_Players\n    where (includeTeams || (!u.aspnet_User.sc_Player.IsTeam))\n    select UserFactory2.CreateFromDbModel(u)).ToList();\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

不确定这是否能解决问题,只是预感。我能够在本地数据库上复制您在 Linqpad 中所做的事情,并且它有效。但我的示例没有返回 IQueryable。您是否在 GetUsers() 之外进一步修改 IQueryable 集合?

\n\n

编辑:

\n\n

我又做了一些检查。仅当我修改示例时才能重复该错误,因此在调用 GetUsers() 后在第二个 Linq 查询中使用了 IQueryable 集合:

\n\n
IQueryable<User> query = GetUsers(true);\n\nvar q = from u in query\n    where u.Name.Contains("Bob")\n    select new {Name = u.FirstName + " " + u.LastName};\n
Run Code Online (Sandbox Code Playgroud)\n\n

我敢打赌,如果您按照上面在 GetUsers() 中建议的方式返回一个列表,错误就会消失。唯一的缺点是,调用 GetUsers() 后执行的任何过滤都不会限制从数据库返回的数据量,因为在调用 .ToList() 时已经执行了查询。

\n\n

编辑2:

\n\n

不幸的是,我不认为\xe2\x80\x99t 认为还有其他方法可以在查询中包含你的工厂方法。我确实还有一个想法。\n您可以为 IQueryable 创建一个扩展方法,将其命名为 ToUserList() 之类的名称。在 ToUserList() 内部,您可以对查询调用 ToList() 以及返回用户集合的工厂方法。使用 Linq 完成数据过滤后,调用此方法。这将允许您仅在准备好从数据库加载数据时才执行查询。下面给出一个例子。

\n\n
public static List<Users> ToUserList(this IQueryable<User> query)\n{\n     return query.ToList().Select(u => UserFactory2.CreateFromDbModel(u)); \n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

像这样调用扩展方法:

\n\n
// Filter the data using linq. When you are ready to execute the query call:\nquery.ToUserList(); // Query will execute and a list of User objects returned.\n
Run Code Online (Sandbox Code Playgroud)\n\n

希望这是有道理的。\nDouglas H.

\n