WCF и Entity Framework с Telerik GridModel

#c# #wcf #telerik

#c# #wcf #telerik

Вопрос:

Это перекрестно размещено на форумах поддержки Telerik.

У меня есть контекст Entity Framework (Code First, 4.1), который используется на уровне службы WCF. Если у меня есть служба, настроенная таким образом:

 public IEnumerable<Dto.PlanMember> GetPlanMembers() {
    var planMembers = from member in this.DataSource.PlanMemberDbSet.Take(10)
                      select new Dto.PlanMember {
                          Id = member.Id,
                          FirstName = member.FirstName,
                          LastName = member.LastName
                      };

    return planMembers;
}
 

Служба работает нормально. Если я настрою это так, следуя примерам привязки сетки через веб-службы

 public GridModel GetPlanMembers(GridState state) {
    var planMembers = from member in this.DataSource.PlanMemberDbSet.Take(10)
                      select new Dto.PlanMember {
                          Id = member.Id,
                          FirstName = member.FirstName,
                          LastName = member.LastName
                      };

    return planMembers.ToGridModel(state);
}
 

Он постоянно получает исключение:

Базовое соединение было закрыто: соединение было неожиданно закрыто.

Я уверен, что это проблема сериализации. По какой-то причине метод ToGridModel расширения не работает должным образом с EFCF 4.1. Что можно сделать, чтобы исправить это?

Это тоже не работает, поэтому это должно быть связано с сериализацией GridModel типа, а не с самим методом расширения, вот в чем проблема:

 public GridModel GetPlanMembers(GridState state) {
    var planMembers = from member in this.DataSource.PlanMemberDbSet.Take(10)
                      select new Dto.PlanMember {
                          Id = member.Id,
                          FirstName = member.FirstName,
                          LastName = member.LastName
                      };

    var gridModel = new GridModel {
        Data = planMembers,
        Total = planMembers.Count()
    };

    return gridModel;
}
 

Ответ №1:

Проблема в том, что выполнение запросов LINQ задерживается. Таким образом, вы возвращаете IQueryable. Данные фактически не извлекаются, пока WCF не попытается их сериализовать. Проблема в том, что ваше соединение уже закрыто в этот момент. Добавьте .ToList() туда, и у вас все должно получиться.

Комментарии:

1. Это было частично правильно. Тем не менее, это привело меня в правильном направлении. В конце концов, я не могу напрямую использовать объекты EFCF, поскольку у меня отложенная загрузка. Тип реального объекта — это динамический прокси, который WCF не может сериализовать. Мне нужно было использовать объекты передачи данных.

2. Если вы отключите создание прокси и отложенную загрузку, вам может сойти с рук отказ от использования DTO. Вы также захотите убедиться, что вы добавляете [DataContract] атрибуты к своим сущностям и указываете IsReference = true . В противном случае вы можете столкнуться с проблемой с циклами в вашем графе объектов. Это все еще может быть проблемой с DTO, если вы включаете ассоциации.