Действительно ли возможно создать пользовательские методы в классах объекта в linq к sql

У меня есть таблица Site в SQL с (среди других) три свойства idReviewer1, idReviewer2, idReviewer3. Теперь я хотел бы создать методы на классе объекта Сайта, чтобы проверить, является ли пользователь рецензентом:

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 к 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?

5
задан doekman 10 June 2010 в 10:18
поделиться

4 ответа

Использовать 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());
2
ответ дан 14 December 2019 в 01:02
поделиться

Я думаю, что вы, возможно, передаете в метод My.DAL.User, а не int, судя по ошибке "'Boolean IsReviewer(My.DAL.User)'". Попробуйте (where s.IsReviewer(user.Id)) и посмотрите, работает ли это?

.
2
ответ дан 14 December 2019 в 01:02
поделиться

К сожалению, возможно, если вы не измените (расширите) провайдер запросов linq2SQL. Провайдер сталкивается с методом, который действительно ему неизвестен, и у него нет возможности узнать, как перевести этот метод в sql. Даже если для этого случая все просто, в общем случае это невозможно (даже опасно). Но вы можете сделать это другим способом. Вы можете сделать delagate (или даже лучше скомпилированный запрос), который берет Site и делает условие, а затем использовать синтаксис метода с

Func<Site,int,Bool> isRevier = (site, idUser) => site.idReviewer1 == idUser || site.idReviewer2 == idUser || site.idReviewer3 == idUser;
.Where(IsReviewer)
2
ответ дан 14 December 2019 в 01:02
поделиться

Вы можете реализовать этот метод как хранимую процедуру , которую затем добавляете в вашу модель 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 в этом случае на самом деле мало что вам выгодно и требует, чтобы вы переместили некоторую логику из приложения в базу данных, что может или не может соответствовать вашей архитектуре.

Связанные ресурсы

3
ответ дан 14 December 2019 в 01:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: