#linq #json #asp.net-mvc-3 #serialization #entity-framework-4
#linq #json #asp.net-mvc-3 #сериализация #entity-framework-4
Вопрос:
У меня есть 3 таблицы в моей базе данных — Conference
ActivityTypes
и таблица соединений ConferenceActivities
. Каждая конференция может иметь ноль или много стандартных действий, и каждое действие может происходить в ноль или более конференций.
Конференция (ConferenceID, ConferenceName)
ConferenceActivities (ConferenceID,ActivityTypeID)
ActivityTypes (ActivityTypeID, ActivityTypeDesc)
Я использовал Entity framework поверх своей существующей базы данных, с помощью шаблонов .tt в приложении MVC3 я сгенерировал DbContext и объекты POCO, отметив, что он генерирует всего два объекта, ActivityType
и Conference
, что приятно, кажется, понимает промежуточную таблицу.
Он также добавляет набор действий в мою конференцию
public virtual ICollection<ActivityType> ActivityTypes { get; set; }
И коллекция конференций для моей деятельности.
public virtual ICollection<Conference> Conferences { get; set; }
Я хотел бы вернуть с помощью JSON объект, соответствующий определенной конференции.. это включает в себя ActivityTypes . Некоторые могут описать этот объект как «shaped» или «jagged», потому что в нем есть коллекция.
Я использую код, подобный следующему, хотя я пробовал много разных вариантов, если у меня был неправильный синтаксис, но я все равно получаю ошибку времени выполнения о рекурсии.
public JsonResult GetConference(int conferenceId)
{
Conference x = context.Conferences.Include("ActivityTypes").FirstOrDefault<Conference>(i => i.EventID == eventId);
return Json(x, JsonRequestBehavior.AllowGet);
}
Похоже, что это не работает «из коробки», и я вижу много вопросов о переполнении стека, которые, похоже, связаны, но, несмотря на попытки множества разных подходов, но все они создают ошибку о рекурсии или конструкторах без параметров.. Я начинаю сомневаться, возможно ли это вообще.
Я попытался присоединить [IgnoreDataMemberAttribute]
or [ScriptIgnore]
к другим свойствам, чтобы остановить его, пытаясь сериализовать рекурсивные отношения (я думаю, что форма не имеет значения, но когда вы в отчаянии ..), И я все еще получаю ту же ошибку.
Я пробовал такой подход, который генерирует ошибку без параметров
var thing = from r in context.Conferences
select new
{
r.ConferenceID,
r.ConferenceName,
ActivityTypes = new List<ActivityType>(
(from c in r.ActivityTypes
select new ActivityType()
{
ActivityTypeDesc = c.ActivityTypeDesc,
ActivityTypeID = c.ActivityTypeID
}).Cast<ActivityType>())
};
return Json(thing, JsonRequestBehavior.AllowGet);
Другим предложением было установить Lazy Loading Enabled
для свойства модели значение false.. что не имело никакого значения, я все еще получаю ошибку рекурсии.
Я попытался удалить Virtual
ключевое слово, которое, как я полагаю, отключает отложенную загрузку .. и пытается.Включить (..) но опять никакой радости.
Другим предложением было изменить метод доступа с public
на internal
, однако это не отличалось от сериализации.
Кто-то также предложил удалить коллекцию конференций из класса activityType, что на самом деле не то, что я хочу сделать .. но выполнение этого просто приводит к ошибке «Указанная схема недействительна». в любом случае.
Я использую, я полагаю, последнюю версию nuget и связанные с ней EF, строительные леса и шаблоны.
Это то, чего я пытаюсь достичь, что должно работать из коробки? Если да, то какие настройки я мог бы пропустить, и если нет, то какова наилучшая практика здесь — единственный способ, которым я знаю, что могу выполнить эту работу, — это создать объект вручную самостоятельно.
Предложения или ссылка на полную рабочую демонстрацию (я видел много предложений и фрагментов кода, которые, похоже, просто не работают !!) приветствуются. Я уверен, что кто-то сделал это и заставил его работать наверняка.
Ответ №1:
не передавайте свои классы моделей. создайте viewmodel с данными, необходимыми для представления, или, в вашем случае, выводом json. я вижу, где вы пытались спроецировать его в анонимный тип, но спроецируйте его в конкретную viewmodel, и он должен работать идеально.