澄清Linq,EntityQuery和RIA Services的交互

时间:2012-03-15 19:56:01

标签: c# silverlight linq entity-framework wcf-ria-services

我有一个关于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可能没有任何方法来编组整个行的查询......对吗?

我的理解是否正确?如果有人可以帮我验证一下,我会很感激。

1 个答案:

答案 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, 理查德