我有以下型号:
public class User
{
public string UserId { get; set; }
public string UserName { get; set; }
public List<Membership> Membership { get; set; }
public bool IsRegistered
{
get { return !String.IsNullOrEmpty(UserName); }
}
}
public class Membership
{
public string MembershipId { get; set; }
public User User { get; set; }
}
在我的Membership
实体的存储库中,我尝试通过执行entries
为IQueryable<Membership>
且orderBy
的{{1}}来执行以下操作来订购我的收藏集LamdaExpression等于{ x => x.User.IsRegistered }
:
ordered = Queryable.OrderBy(ordered, orderBy);
当我尝试这个时,我收到以下错误:
指定的类型成员&#39; IsRegistered&#39; LINQ不支持 实体。仅初始化程序,实体成员和实体导航 支持属性。
如何通过不在数据库中的属性来订购我的收藏?
提前致谢。
答案 0 :(得分:3)
由于IsRegistered是客户端函数,因此您需要使用LINQ over objects进行排序。您可以将LINQ over SQL转换为LINQ over objects,方法是枚举它。然后,一旦它是一个LINQ over对象,你就可以使用LINQ over itect的OrderBy来命令它。这样做的常用方法是调用ToList,如:
ordered = Queryable.ToList().OrderBy(ordered, orderBy);
如果要对数据库进行排序,则需要将客户端代码转换为与SQL兼容的代码,例如:
ordered = Queryable.OrderBy(ordered, (x=>x.User.UserName!=null && x.User.UserName!=''));
答案 1 :(得分:2)
您始终可以在本地进行排序。如果您希望将计算属性用于服务器端排序,则需要一个LINQ提供程序(EF)可以转换的表达式(在您的情况下为SQL)。
对于!String.IsNullOrEmpty(UserName)
,您可以使用适用于LINQ2SQL的m=>String.Empty!=(m.User.UserName??String.Empty)
。检查生成的SQL时,您应该得到类似
-- Region Parameters
DECLARE @p0 NVarChar(1000) = ''
DECLARE @p1 NVarChar(1000) = ''
-- EndRegion
SELECT --fields
FROM [Membership] as [t0]
JOIN User AS [t1]
ON -- id
WHERE -- your predicate
ORDER BY
(CASE
WHEN @p0 <> (COALESCE([t1].[UserName],@p1)) THEN 1
WHEN NOT (@p0 <> (COALESCE([t1].[UserName],@p1))) THEN 0
ELSE NULL
END)
我想EF也会翻译它。
答案 2 :(得分:0)
你做不到。实体框架的order by映射到db字段,因为它在SQL端调用“ORDER BY”子句。
如果你真的想通过非db字段订购你的记录(但是,据我所知,你可以在这种情况下通过UserName订购你的记录),你应该过滤你的记录,调用ToList()和OrderBy(很明显这只是从数据库服务器返回结果后的记录顺序)。