У меня есть таблица 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?
Использовать 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());
Я думаю, что вы, возможно, передаете в метод My.DAL.User, а не int, судя по ошибке "'Boolean IsReviewer(My.DAL.User)'". Попробуйте (where s.IsReviewer(user.Id)) и посмотрите, работает ли это?
.К сожалению, возможно, если вы не измените (расширите) провайдер запросов linq2SQL. Провайдер сталкивается с методом, который действительно ему неизвестен, и у него нет возможности узнать, как перевести этот метод в sql. Даже если для этого случая все просто, в общем случае это невозможно (даже опасно). Но вы можете сделать это другим способом. Вы можете сделать delagate (или даже лучше скомпилированный запрос), который берет Site и делает условие, а затем использовать синтаксис метода с
Func<Site,int,Bool> isRevier = (site, idUser) => site.idReviewer1 == idUser || site.idReviewer2 == idUser || site.idReviewer3 == idUser;
.Where(IsReviewer)
Вы можете реализовать этот метод как хранимую процедуру , которую затем добавляете в вашу модель 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 в этом случае на самом деле мало что вам выгодно и требует, чтобы вы переместили некоторую логику из приложения в базу данных, что может или не может соответствовать вашей архитектуре.
Связанные ресурсы