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)
问题是因为您在 GetUsers 方法中返回 IQueryable 吗?尝试返回 List。这将强制 Linq 查询在该方法内执行。
\n\npublic 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}\nRun Code Online (Sandbox Code Playgroud)\n\n不确定这是否能解决问题,只是预感。我能够在本地数据库上复制您在 Linqpad 中所做的事情,并且它有效。但我的示例没有返回 IQueryable。您是否在 GetUsers() 之外进一步修改 IQueryable 集合?
\n\n编辑:
\n\n我又做了一些检查。仅当我修改示例时才能重复该错误,因此在调用 GetUsers() 后在第二个 Linq 查询中使用了 IQueryable 集合:
\n\nIQueryable<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};\nRun 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\npublic static List<Users> ToUserList(this IQueryable<User> query)\n{\n return query.ToList().Select(u => UserFactory2.CreateFromDbModel(u)); \n}\nRun 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.\nRun Code Online (Sandbox Code Playgroud)\n\n希望这是有道理的。\nDouglas H.
\n