Перехватчик запросов служб данных ADO.NET (WCF) вешает IIS - PullRequest
0 голосов
/ 25 марта 2010

У меня есть служба данных 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/

1 Ответ

0 голосов
/ 26 марта 2010

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

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

Alex

...