Передача объекта Entity Framework Context в WCF - PullRequest
2 голосов
/ 11 декабря 2011

Мне нужно передать объект Context из EF в метод WCF.

Обычно я создаю объект Context в методе WCF и удаляю его непосредственно перед завершением вызова метода, который прекрасно работает для большинства моих методов.

Однако мне нужно передать объект Context (в частности, DBContext) из контроллера MVC в мой конкретный метод WCF, потому что у меня включено кэширование для некоторых справочных таблиц. Мне нужен этот конкретный объект Context (который я установил в методе Application_Start файла Global.asax), а не то, что я делаю в предложении выше, потому что я использую этот конкретный объект для SqlDependency. Если я попытаюсь создать совершенно новый объект DBContext, я не смогу использовать SqlDependency, потому что получаю сообщение об ошибке, сообщающее, что SqlDependency необходимо включить перед вызовом базы данных.

Проблема в том, что я получаю следующую ошибку (сокращенно для краткости), когда я пытаюсь запустить свой инструмент Test Client WCF, который, как я знаю, имеет отношение к неправильному объявлению атрибута KnownType (то есть объекта DBContext). Обратите внимание, что проект WCF компилируется просто отлично. Мне нужна помощь с этой конкретной частью, так как я никогда не использовал KnownType в моей службе WCF. Все они были простыми типами (int, string и т. Д.).

Ошибка: невозможно получить метаданные из http://localhost:8732/Design_Time_Addresses/YeagerTechWcfService/YeagerTechWcfService/mex

Если это служба Windows (R) Communication Foundation, к которой вы иметь доступ, пожалуйста, убедитесь, что вы включили публикацию метаданных на указанный адрес. Для получения помощи по включению публикации метаданных, пожалуйста, обратитесь к документации MSDN по адресу http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Обмен

Ошибка URI: http://localhost:8732/Design_Time_Addresses/YeagerTechWcfService/YeagerTechWcfService/mex Метаданные содержат ссылку, которая не может быть разрешена:

В моей службе WCF есть следующий код OperationContract:

[OperationContract]
        IEnumerable<Category> GetCategories(YeagerTechEntities DbContext);

В моей службе WCF есть следующий код DataContract:

namespace YeagerTechModel
{
    [Serializable]
    [DataContract(IsReference = true)]
    [KnownType(typeof(YeagerTechEntities))]
    public partial class Category
    {
        public Category()
        {
            this.Projects = new HashSet<Project>();
        }

        [DataMember]
        public short CategoryID { get; set; }
        [DataMember]
        public string Description { get; set; }

        [DataMember]
        public virtual ICollection<Project> Projects { get; set; }
    }

}

Наконец, мой метод WCF состоит в следующем:

public IEnumerable<YeagerTechModel.Category> GetCategories(YeagerTechEntities DbContext)
        {
            //YeagerTechEntities DbContext = new YeagerTechEntities();

            DbContext.Configuration.ProxyCreationEnabled = false;

            IEnumerable<YeagerTechModel.Category> category = DbContext.Categories.Where(p => p.CategoryID > 0).AsCached("Categories").ToList();
            //IEnumerable<YeagerTechModel.Category> category = DbContext.Categories.Where(p => p.CategoryID > 0);

            CloseConnection(DbContext);

            return category;
        }

1 Ответ

1 голос
/ 11 декабря 2011

Вам нужен одноэлементный объект по шаблону реестра / службы. Этот объект будет содержать ссылку на ваши глобальные объекты. Например, при запуске приложения вы будете заполнять этот объект своим контекстом, используя SqlDependency, и вы будете использовать реестр для доступа к этому контексту в действиях вашего контроллера и сервисах.

В любом случае, работайте с этим очень осторожно. SqlDependency и EF плохо играют вместе, потому что это продлит ваш контекст. Долгоживущий контекст в большинстве случаев анти-паттерн . Никогда не используйте этот контекст для чего-либо еще, кроме загрузки кэшированных данных. Не используйте его для модификации данных или загрузки не кешированных отношений! Загрузите сущности как неотслеживаемые (AsNoTracking метод расширения по запросу) в первом запросе и отключите создание прокси и отложенную загрузку для этого контекста.

Также следует помнить, что запрос в EF всегда выполняется в базе данных. Я не уверен, что должен делать ваш AsCached, но я почему-то сомневаюсь, что это сработает. Вероятно, вам нужно:

var category = DbContext.Categories.Local
                        .Where(p => p.CategoryID > 0)
                        .ToList();

Я бы не использовал SqlDependency с EF. Я бы использовал ADO.NET и SQL напрямую. Для кэширования в EF я бы проверил провайдер EF Caching , чтобы использовать кэш второго уровня, которого в большинстве случаев достаточно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...