Перехватчик запросов служб данных ADO.NET (WCF) зависает в IIS

У меня есть служба данных ADO.NET, которая должна предоставлять доступ только для чтения к довольно сложной базе данных.

По логике вещей в моей модели данных есть наследование «таблица на тип» (TPT), но EDM не реализует наследование. (Ограничение служб данных и свойств навигации для производных типов. ВСЕ ЕЩЕ не исправлено в .NET 4!) Я могу запросить свой EDM напрямую (используя отдельный проект), используя копию запроса, который я пытаюсь выполнить для веб-службы, результаты возвращаются в течение 10 секунд. Отключение перехватчиков запросов. Я могу сделать тот же запрос к веб-службе, результаты возвращаются так же быстро. Я могу включить некоторые перехватчики запросов, и результаты будут возвращаться медленно, примерно через минуту. В качестве альтернативы я могу включить все перехватчики запросов, расширить меньше свойств основного объекта, который я запрашиваю, и результаты будут возвращены за аналогичный период времени. (Я увеличил некоторые периоды тайм-аута)

До этого момента Sql Profiler указывает, что замедление происходит в базе данных. (Это сообщение для другого дня) Но когда я включаю все свои перехватчики запросов и расширяю все свойства, я бы хотел, чтобы рабочий процесс IIS привязывал ЦП в течение 20 минут, а запрос даже к базе данных никогда не выполнялся, т. Е. запрос никогда не проходит мимо веб-сервера. Для меня это означает, что да, моя реализация, вероятно, отстой, но независимо от того, на каком «уровне» служб данных есть проблемы, не должно быть. Трассировка 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, как указано выше.

Образец запроса

Этот образец запроса представляет собой всего лишь образец, предназначенный для демонстрации третьим сторонам того, как получить доступ к данным с помощью предоставленной веб-службы. Я понимаю, что у производственного запроса не так много расширений. (Но также помните, что для получения всего объекта в смысле ООП мне нужны строки 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);

Любые предложения или советы будут в значительной степени связаны с исправлением моей текущей реализации или при разработке новой с оговоркой, что существующая логика базы данных не может быть изменена (хотя я могу добавить к ней) и что в конечном итоге мне нужно раскрыть большой часть базы данных через веб-службу, которая ограничивает доступ к данным авторизованными данными с целью интеграции данных с несколькими внешними сторонами. Эти внешние стороны будут выполнять регулярные пакетные задания для импорта наших данных в свою базу данных / хранилище данных.

СПАСИБО!!!

ОБНОВЛЕНИЕ: опубликовал эту проблему в MSDN, получил аналогичные отзывы. http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataservices/thread/1ccfc96c-dd35-4879-b36b-57e915d5e02f/


person Community    schedule 25.03.2010    source источник
comment
Просто небольшое примечание: EF может обрабатывать навигацию по производным типам, отображаемым с помощью TPT ... это не могут сделать службы данных.   -  person Alex James    schedule 26.03.2010
comment
Ах, хороший улов, слишком много времени бился головой о стену, и я все перепутал. Спасибо.   -  person    schedule 30.03.2010


Ответы (1)


Я просто догадываюсь ... но делать так много расширений - это почти никогда не лучшая идея. Запрос, несомненно, превратится в довольно ужасный SQL, который легко может вызвать тайм-ауты.

Добавьте TPT в уравнение, и все станет только хуже :(

Алекс

person Alex James    schedule 26.03.2010