我有一个关于linq与entityquery和ria服务的交互的一般性问题。我知道在我的domainconext中我可以为我的应用程序定义查询。例如,我可以在domaincontext中使用linq来定义以下查询:
public IQueryable<User> GetUsersFriends(Guid usersID)
{
return (from f in this.ObjectContext.Friends join u in this.ObjectContext.Users on f.FriendUsersID equals u.ID where f.UsersID.Equals(usersID) select u);
}
这一切都很好。但我的问题是,我可以从客户端(silverlight应用程序)执行相同类型的查询吗?那么我可以针对EntityQuery对象构建linq语句并以这种方式从数据库返回数据吗?
我知道我可以对已经加载的实体集合执行linq操作吗?我可以在客户端使用linq来加载集合吗?
我认为最终命中数据库的所有查询都需要在我的域上下文中定义?出于习惯的原因,我一直试图使用linq来定义新的查询并将它们传递给domaincontext.load()操作....这种操作失败了。 domainconext可能没有任何方法来编组整个行的查询......对吗?
我的理解是否正确?如果有人可以帮我验证一下,我会很感激。
答案 0 :(得分:2)
IQueryable的一个主要优点(也是一个非常好的安全风险)是,您可以在客户端创建查询,并将其序列化回服务器以便在服务上进行处理。这里的要求是它必须返回已定义的类型(在您的情况下为IQueryable,其中User是必须在支持IEnumerable&lt;&gt;的集合中返回的类型。
我从Shawn Wildermuth(wildermuth.com)那里得到了我的例子,并稍微调整了一下。这就是我在客户端“模型”中使用的内容。
publicvoid PerformQuery<T>(EntityQuery<T> qry, EventHandler<EntityResultsArgs<T>> evt, object pUserState = null, bool NoRecordsThrow = False, LoadBehavior pLoadBehavior = LoadBehavior.MergeIntoCurrent ) where T : Entity
{
ModelDataContext.Load<T>(
qry,
pLoadBehavior,
r =>
{
if (evt != null)
{
try
{
if (r.HasError)
{
#if DEBUG
System.Diagnostics.Debugger.Break();
#endif
//internal class to record error messages
AppMessages.ErrorMessage.Display(string.Concat(r.Error.Message, Environment.NewLine, "------------------------", "------- Stack Trace ------", Environment.NewLine, r.Error.StackTrace));
}
else if (r.Entities.Count() > 0 || NoRecordsThrow)
evt(this, new EntityResultsArgs<T>(r.Entities, r.UserState));
}
catch (Exception ex)
{
#if DEBUG
System.Diagnostics.Debugger.Break();
#endif
evt(this, new EntityResultsArgs<T>(ex));
}
}
},
pUserState);
}
然后我会这样使用它:
var UserQuery = <DomainServiceName>.Users.Where(pUser => pUsers.City == "Calgary");
PerformQuery<User>(UserQuery, UserQueryComplete)
缺点是通过这一个端点,可以使用客户端发布的任何类型的过滤器提取用户数据....
HTH, 理查德