Я создаю приложение, используя MVC3, механизм просмотра Razor, шаблон репозитория с единицей работы и использую код EF4.1 Code First для определения моей модели данных.
Вот немного фон (закройте его, если хотите).
Само приложение представляет собой просто «Меню» интрасети.
Двумя основными объектами являются MenuItem и Department, из которых:
Вот как я определил свои Entities
public class MenuItem
{
public int MenuItemId { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public virtual ICollection<Department> Departments { get; set; }
public int? ParentId { get; set; }
public virtual MenuItem ParentMenuItem { get; set; }
}
public class Department
{
public int DepartmentId { get; set; }
public string Name { get; set; }
public virtual ICollection<MenuItem> MenuItems { get; set; }
}
Я использую FluentAPI для определения Self Reference Many-to-Many для MenuItem.
Проблема, с которой я сталкиваюсь, заключается в передаче MenuItem в представление через JSON. Основные проблемы заключаются в том, что у меня есть циклическая ссылка между моими объектами, с которыми встроенный анализатор JSON не может справиться, и у меня все еще включена отложенная загрузка и создание прокси.
Я использую библиотеку JSON.net из Nuget в качестве своего JSON Сериализатор, поскольку это, кажется, хороший способ решить проблему с круговой ссылкой. Теперь я не знаю, как «исправить» проблему с генерацией прокси. В настоящее время сериализатор выдает Объект RelationshipManager не может быть сериализован. Этот тип объекта не может быть сериализован, если RelationshipManager принадлежит объекту сущности, который не реализует IEntityWithRelationships.
Кто-нибудь может мне с этим помочь? Если я отключу создание прокси, у меня будет чертовски много времени на загрузку всех дочерних элементов MenuItem, поэтому я очень хочу оставить это включенным. Я прочитал довольно много, и, похоже, есть множество разных ответов, включая проецирование сущностей в другой объект, сериализацию его и т. Д. И т. Д. В идеале можно было бы каким-то образом настроить JSON.net, чтобы игнорировать объект RelationshipManager?
Обновление
Вот то, что я использовал в качестве Custom ContractResolver для сериализатора JSON.Net. Кажется, это решило мою проблему.
public class ContractResolver : DefaultContractResolver
{
private static readonly IEnumerable<Type> Types = GetEntityTypes();
private static IEnumerable<Type> GetEntityTypes()
{
var assembly = Assembly.GetAssembly(typeof (IEntity));
var types = assembly.GetTypes().Where(t => String.Equals(t.Namespace, "Namespace", StringComparison.Ordinal));
return types;
}
protected override List<MemberInfo> GetSerializableMembers(Type objectType)
{
if (!AllowType(objectType))
return new List<MemberInfo>();
var members = base.GetSerializableMembers(objectType);
members.RemoveAll(memberInfo => (IsMemberEntityWrapper(memberInfo)));
return members;
}
private static bool AllowType(Type objectType)
{
return Types.Contains(objectType) || Types.Contains(objectType.BaseType);
}
private static bool IsMemberEntityWrapper(MemberInfo memberInfo)
{
return memberInfo.Name == "_entityWrapper";
}
}
IEntity
- это интерфейс, который реализуют все мои объекты сущностей Code First.