是否可以在linq to sql中的实体类中创建自定义方法

时间:2010-06-10 08:22:53

标签: .net visual-studio-2008 linq-to-sql .net-3.5

我在SQL中有一个表Site,其中包括三个属性idReviewer1idReviewer2idReviewer3。现在我想在Site的实体类上创建一个方法来检查用户是否是审阅者:

partial class Site
{
    public bool IsReviewer(int idUser)
    {
        return idReviewer1 == idUser || idReviewer2 == idUser || idReviewer3 == idUser;
    }
}

我这样用它:

return from s in db.Sites
       where s.IsReviewer(user)
       select s;

但是,Linq to SQL不知道如何将其转换为SQL。我收到以下错误消息:

Method 'Boolean IsReviewer(Int32)' has no supported translation to SQL.

我宁愿不写这个:

return from s in db.Sites
       where idReviewer1 == idUser || idReviewer2 == idUser || idReviewer3 == idUser
       select s;

有没有办法将此功能放在一个地方,而不需要使用SQL?

4 个答案:

答案 0 :(得分:3)

您可以将该方法实现为存储过程,然后将其作为函数添加到LINQ to SQL模型中。然后你就可以做类似的事情:

ISingleResult<Site> sites = db.SelectSitesByReviewer(userId);

或者,您可以将其实现为用户定义函数(UDF),这将允许您在LINQ查询中使用它:

IEnumerable<Site> sites = from site in db.Sites
                          where db.IsReviewer(site.Id, userId)
                          select site;

但是,我没有看到像您在问题中提到的那样定义LINQ查询时出现任何问题。在这种情况下使用存储过程或UDF并不会给您带来太大的影响,并且需要您将一些逻辑从应用程序移到数据库中,这可能符合您的架构,也可能不符合您的架构。

相关资源

答案 1 :(得分:2)

我认为您可能会根据错误“'Boolean IsReviewer(My.DAL.User)'”将My.DAL.User而不是int传递给您的方法。尝试(其中s.IsReviewer(user.Id))并查看是否有效?

答案 2 :(得分:2)

不幸的是可能知道,除非你改变(扩展)linq2SQL查询提供程序。提供者遇到的方法实际上并不为他所知,并且他无法知道如何将方法转换为sql。即使对于这种情况,一般来说它很简单(甚至是危险的)。 但你可以用另一种方式做到这一点。 您可以创建一个delagate(甚至更好的编译查询),它接受一个Site并执行该条件,然后使用方法语法

Func<Site,int,Bool> isRevier = (site, idUser) => site.idReviewer1 == idUser || site.idReviewer2 == idUser || site.idReviewer3 == idUser;
.Where(IsReviewer)

答案 3 :(得分:2)

使用Func而不是方法调用。

partial class Site  
{  
    public static Func<Site, bool> IsReviewer(int idUser)  
    {  
        return (s => s.idReviewer1 == idUser 
          || s.idReviewer2 == idUser 
          || s.idReviewer3 == idUser);  
    }  
}  

return db.Sites.Where(Site.IsReviewer());