【问题标题】:Clarification of interaction of Linq, EntityQuery, and RIA Services澄清 Linq、EntityQuery 和 RIA 服务的交互
【发布时间】:2012-03-15 19:56:00
【问题描述】:

我有一个关于 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);
    }

这一切都很好。但我的问题是,我可以从 client side (silverlight app) 执行相同类型的查询吗?那么我可以针对 EntityQuery 对象构建一个 linq 语句并以这种方式从数据库中返回数据吗?

我知道我可以对已经已加载的实体集合执行 linq 操作?我可以在客户端使用 linq 来加载集合吗?

我认为所有最终访问数据库的查询都需要在我的域上下文中定义?出于习惯,我一直在尝试使用 linq 来定义新的查询并将这些查询传递给 domaincontext.load() 操作....失败得很惨。 domainconext 可能没有任何方法可以跨行编组查询...对吗?

我的理解正确吗?如果有人可以帮我验证这一点,我将不胜感激。

【问题讨论】:

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


    【解决方案1】:

    IQueryable 的主要优点之一(它也是一个很好的安全风险)是您可以在客户端创建查询,并将其序列化回服务器以在服务端进行处理。这里的要求是它必须返回已定义的类型(在您的情况下为 IQueryable,其中 User 是必须在支持 IEnumerable 的集合中返回的类型。

    我从 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, 理查德

    【讨论】:

    • 谢谢理查德。这对我来说确实有点清楚。当我最终尝试类似的事情时,我收到了一条关于没有立即有意义的类型的错误消息。通过您的解释,我现在明白是模板化加载 (domaincontext.load) 可以解决我的问题。但是,我明白你关于控制数据库被击中的方式的观点,所以我现在可能不会这样做,只是将所有内容放在域上下文中。不过,我不明白您对安全性的评论。你能解释一下吗?只是为了我自己的熏陶。
    • 使用公开为 IQueryable 的端点,您可以使用任何类型的过滤器、排序子句等从该实体中检索信息。您允许用户编写查询,然后将该查询传递给信息检索的端点。当您“包含”附加信息或允许延迟加载时,这会变得更加危险。这两者都意味着从实体开始,您可以导航到您的数据模式并检索其他信息。请记住,这是通过 IIS 公开的一个端点——如果 IIS 是公共的,那么这个入口点也是公共的。安全是一个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-25
    • 1970-01-01
    • 2011-04-11
    相关资源
    最近更新 更多