目前我试图通过可重复使用的代码来查询我的查询,以检查帖子是否有资格显示。
// Logic to check if post is eligible for display
public bool isEligibleForDisplay(Post n)
{
var pubDate = n.PUBLISH_DATE ?? DateTime.MinValue;
var endDate = n.END_DATE ?? DateTime.MaxValue;
var correctState = (n.STATE == PostState.Publish || n.STATE == PostState.Furture);
var dateInRange = (DateTime.Now >= pubDate && DateTime.Now <= endDate);
return correctState && dateInRange;
}
我的linq看起来像这样:
var q = from n in _db.Posts
where isEligibleForDisplay(n)
group n by n.POST_ID into g
select g.OrderByDescending(t => t.CREATE_DATE).First();
return q.Take(quantity);
我第一次使用linq到sql时遇到“SQL中没有支持的翻译”问题,我只是想知道是否有任何可以用作这种情况的解决办法,如果我包括这可能会很麻烦每次都将大量的检查逻辑放入我的查询中。
我很期待回复。谢谢!
答案 0 :(得分:2)
您可以在SQL服务器上创建一个名为isEligibleForDisplay
的函数,该函数执行这些检查的SQL等效项并将其添加到您的dbml文件中。
我没有对此进行过测试,但我认为最简单的方法是创建一个传递所需值的函数,而不是整个记录,我觉得这样的东西可能有效:
CREATE FUNCTION isEligibleForDisplay(
@publishDate DATETIME,
@endDate DATETIME,
@state TINYINT -- correct me if i'm wrong...
) RETURNS bit
AS
BEGIN
DECLARE @return bit
DECLARE @dateStart DATETIME, @dateEnd DATETIME
SET @return = 0
SET @dateStar t= COALESCE(@publishDate, CONVERT(DATETIME, '1900-01-01'))
SET @dateEnd = COALESCE(@endDate, CONVERT(DATETIME, '9999-12-31'))
IF getdate() BETWEEN @dateStart AND @dateEnd
BEGIN
IF @state IN(1,3) -- or whatever the int representations of your enum are
SET @return = 1
END
RETURN @return
END
答案 1 :(得分:1)
我使用了linq的扩展来包含一个方法,使用IQueryable实际上可以很好地工作。
public static IQueryable<T> getPostActive<T>(this IQueryable<T> items) where T : P015.Models.SQLModel.Post
{
// Logic to check if post is eligible for display
var now = DateTime.Now;
return items.Where(n =>
(n.STATE.Trim() == PostState.Publish || n.STATE.Trim() == PostState.Furture || n.STATE.Trim() == PostState.Draft) &&
(
((n.END_DATE ?? SqlDateTime.MaxValue.Value) >= now) &&
((n.PUBLISH_DATE ?? SqlDateTime.MinValue.Value) <= now)
)
);
}
答案 2 :(得分:0)
_db.Posts中有多少条记录?如果不多,你可以先做.ToList(),而不是linq就可以使用isEligibleForDisplay函数。