2009-09-02 40 views
6

我在我的数据库模型的顶部有一个模型并映射了我的Repository中的对象。如何使用linq for sql使用工厂类?

但是,显然,我是否直接在我的GetUsers中选择“新建”或“select factoryresult”,如下所示。我在运行时得到错误,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 
        }; 
    } 

回答

1

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

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

不知道这是否会解决问题,只是一个预感。我能够在本地数据库中复制Linqpad中正在执行的操作,并且工作正常。但我的示例没有返回IQueryable。你是否正在修改GetUsers()之外的IQueryable集合?

编辑:

我做多一些检查。我可以只复制错误,当我修改我的样本,因此IQueryable的集合在第二Linq查询使用调用GetUsers()后:

IQueryable<User> query = GetUsers(true); 

var q = from u in query 
    where u.Name.Contains("Bob") 
    select new {Name = u.FirstName + " " + u.LastName}; 

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

编辑2:

不幸的是,我不认为有任何其他办法,包括在查询你的工厂方法。我还有一个想法。 您可以为IQueryable创建扩展方法,将其称为ToUserList()。在ToUserList()内部,您可以在查询上调用ToList(),并返回一组用户的工厂方法。当您完成使用Linq过滤数据时调用此方法。这将允许您仅在准备好从数据库加载数据时才执行查询。下面给出一个例子。

public static List<Users> ToUserList(this IQueryable<User> query) 
{ 
    return query.ToList().Select(u => UserFactory2.CreateFromDbModel(u)); 
} 

调用扩展方法是这样的:

// Filter the data using linq. When you are ready to execute the query call: 
query.ToUserList(); // Query will execute and a list of User objects returned. 

希望这是有道理的。 Douglas H.

+0

感谢道格拉斯和Rossisdead, 我已经试过转换打电话给我的工厂方法之前上市,但我不仅要返回所有的LINQ对象从数据库,我必须构建我所有的域模型对象 - 我试图找到一种方式,不需要...此外,我在我的服务层进行过滤,将不得不将该列表转换回可查询。 ... – 2009-09-11 08:20:02

+0

嗨安德斯, 请参阅上面的编辑2。 – Douglas 2009-09-11 14:57:19

+0

嗨,道格拉斯, 我把你的答复标记为答案,但我希望保持数据库linq对象在你的建议将数据层对象暴露给服务层的数据层。 – 2009-09-12 11:58:08

1

这个错误几乎可以解释这一切。

“方法CreateFromDbModel没有翻译到SQL(系统。NotSupportedException)“

您的CreateFromDbModel方法不是一个sql函数,您的应用程序将无法运行CreateFromDbModel函数,直到对象从服务器明确返回给您,您很可能必须调用ToList(),或在您的查询之前,你可以在上面运行CreateFromDbModel类似的东西。