ADO.NET(WCF)数据服务查询拦截器挂起IIS

时间:2010-03-25 18:20:41

标签: wcf entity-framework authorization wcf-data-services

我有一个ADO.NET数据服务,它应该提供对稍微复杂的数据库的只读访问。

逻辑上我的数据模型中有每个类型的表(TPT)继承,但EDM没有实现继承。 (派生类型的数据服务和导航属性的限制。在.NET 4中没有修复STILL!)我可以使用我试图针对Web服务运行的查询的副本直接查询我的EDM(使用单独的项目),结果在10秒内返回。禁用查询拦截器我能够对Web服务进行相同的查询,结果也会快速返回。我可以启用查询拦截器的部分,并且结果会缓慢返回,大约一分钟左右。或者,我可以启用所有查询拦截器,在我查询的主对象上扩展较少的属性,并在相似的时间段内返回结果。 (我增加了一些超时时间)

直到这一点,Sql Profiler指示减速是数据库。 (这是不同日期的帖子)但是当我启用所有查询拦截器并展开所有属性时,我希望IIS工作进程将CPU挂起20分钟,甚至不会对数据库进行查询,即查询永远不会通过Web服务器。这对我来说意味着是的,我的实现可能很糟糕,但无论数据服务“层”是否存在问题,它都不应该。 WCF追踪没有透露任何有趣的未经训练的眼睛。

详细说明:

  • 数据模型:代理 - >人员 - >学生
  • 学生有一系列推介
  • 学生和推荐是私人的,针对网络服务的查询应该只返回“您的”学生和推荐人。这意味着人员和代理也需要过滤。任何已经过身份验证的人都可以访问其他实体(代理 - >组织 - >学校)。
  • 现有的安全模型不适合对这种类型的数据访问执行此类过滤,查询拦截器很复杂,导致EF生成一些有趣的 sql查询。

示例拦截器

[QueryInterceptor("Agents")]
    public Expression<Func<Agent, Boolean>> OnQueryAgents()
    {
        //Agent is a Person(1), Educator(2), Student(3), or Other Person(13); allow if scope permissions exist
    return ag =>
               (ag.AgentType.AgentTypeId == 1 || ag.AgentType.AgentTypeId == 2 || ag.AgentType.AgentTypeId == 3 || ag.AgentType.AgentTypeId == 13) &&                
            ag.Person.OrganizationPersons.Count<OrganizationPerson>(op =>
                op.Organization.ScopePermissions.Any<ScopePermission>
                    (p => p.ApplicationRoleAccount.Account.UserName == HttpContext.Current.User.Identity.Name && p.ApplicationRoleAccount.Application.ApplicationId == 124) ||
                op.Organization.HierarchyDescendents.Any<OrganizationsHierarchy>(oh => oh.AncestorOrganization.ScopePermissions.Any<ScopePermission>
                    (p => p.ApplicationRoleAccount.Account.UserName == HttpContext.Current.User.Identity.Name && p.ApplicationRoleAccount.Application.ApplicationId == 124))) > 0; 
    }

Person,Student,Referral的查询拦截器都非常相似,即它们遍历多个相同/相似的表以查找ScopePermissions,如上所述。

示例查询

此示例查询只是一个示例,旨在向第三方说明如何使用提供的Web服务访问数据。我意识到生产查询不会有那么多扩展。 (但是还要记住,为了在OOP意义上获得整个对象,我需要一个Agent,Person和Student行。)

var referrals =
            (from r in service.Referrals
                 .Expand("Organization/ParentOrganization")              
                 .Expand("Educator/Person/Agent")
                 .Expand("Student/Person/Agent")
                 .Expand("Student")
                 .Expand("Grade")
                 .Expand("ProblemBehavior")
                 .Expand("Location")
                 .Expand("Motivation")
                 .Expand("AdminDecision")
                 .Expand("OthersInvolved")
             where
                 r.DateCreated >= coupledays &&
                 r.DateDeleted == null
             select r);

任何建议或提示都会大大关联,以修复我当前的实现或开发一个新的实现,但需要注意的是现有的数据库逻辑无法更改(尽管我可以添加它),最终我需要通过Web服务公开数据库的大部分,该服务限制对授权数据的数据访问,以便与多个外部方进行数据集成。这些外部各方将执行常规批处理作业,以将我们的数据导入其数据库/数据仓库。

谢谢!!!

更新:在MSDN上发布此问题,收到了类似的反馈。 http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataservices/thread/1ccfc96c-dd35-4879-b36b-57e915d5e02f/

1 个答案:

答案 0 :(得分:0)

我只是在这里猜测...但做那么多扩展几乎从来都不是一个好主意。该查询无疑将扩展为一些非常糟糕的SQL,这很容易导致超时。

将TPT添加到等式中,事情变得更糟:(

亚历