Я провел несколько дней, пытаясь решить эту проблему. Делая простой проект, иллюстрирующий мою проблему, я наткнулся на возможное решение. Итак, это своего рода двойной вопрос.
Но сначала небольшая справочная информация:
Я только начал использовать Entity Framework 4.1 (EF) и Code First для создания моделей для моего проекта ASP.NET MVC. Мне нужно несколько моделей, подобных этой:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace TestApp.Models
{
public class Family
{
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Father> Fathers { get; set; }
public virtual ICollection<Mother> Mothers { get; set; }
}
public class Mother
{
public int ID { get; set; }
public string Name { get; set; }
public int FamilyID { get; set; }
public virtual ICollection<Child> Children { get; set; }
public virtual Family Family { get; set; }
}
public class Father
{
public int ID { get; set; }
public string Name { get; set; }
public int FamilyID { get; set; }
public virtual ICollection<Child> Children { get; set; }
public virtual Family Family { get; set; }
}
public class Child
{
public int ID { get; set; }
public string Name { get; set; }
public int MotherID { get; set; }
public int FatherID { get; set; }
public virtual Mother Mother { get; set; }
public virtual Father Father { get; set; }
}
}
И DbContext:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
namespace TestApp.Models
{
public class TestContext : DbContext
{
public DbSet<Family> Families { get; set; }
public DbSet<Mother> Mothers { get; set; }
public DbSet<Father> Fathers { get; set; }
public DbSet<Child> Children { get; set; }
}
}
(Пожалуйста, извините за неудачный пример, вот что смог придумать мой пятничный жареный мозг.)
В семье может быть несколько матерей и несколько отцов. И у ребенка есть мать и отец. Я проверил одного из гуру .NET на моей работе, который согласился, что в этом нет ничего экстраординарного. По крайней мере, насколько мы можем видеть.
Но когда я запускаю код, я получаю это исключение:
System.Data.SqlServerCe.SqlCeException: ссылочная связь приведет к циклической ссылке, которая не разрешена. [Имя ограничения = Mother_Family]
Я вижу цикл: Family - Mother - Child - Father - Family
. Но если бы я сам создал таблицы базы данных (что я предпочитаю не делать, это то, что мне нравится в Code First), то, насколько я могу судить, это была бы совершенно правильная структура данных.
Итак, мой первый вопрос: Почему это проблема при первом использовании кода? Есть ли способ рассказать EF, как правильно обрабатывать цикл?
Затем, когда я писал изначально, создавая простой проект, иллюстрирующий мою проблему, я случайно наткнулся на возможное решение. Я просто забыл некоторые свойства при определении моих моделей. Для ясности в следующем примере вместо удаления я закомментировал части моделей, которые я забыл:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace TestApp.Models
{
public class Family
{
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Father> Fathers { get; set; }
public virtual ICollection<Mother> Mothers { get; set; }
}
public class Mother
{
public int ID { get; set; }
public string Name { get; set; }
// public int FamilyID { get; set; }
public virtual ICollection<Child> Children { get; set; }
public virtual Family Family { get; set; }
}
public class Father
{
public int ID { get; set; }
public string Name { get; set; }
// public int FamilyID { get; set; }
public virtual ICollection<Child> Children { get; set; }
public virtual Family Family { get; set; }
}
public class Child
{
public int ID { get; set; }
public string Name { get; set; }
// public int MotherID { get; set; }
// public int FatherID { get; set; }
public virtual Mother Mother { get; set; }
public virtual Father Father { get; set; }
}
}
Итак, удаление этих SomethingID
справочных свойств, похоже, решает мою проблему. Как вы можете видеть в контроллере примера проекта, на который я ссылаюсь в конце этого поста, я все еще могу циклически повторяться и делать что-то вроде mothers.First().Family.Fathers.First().Children.First().Mother.Family.Name
без каких-либо проблем. Но все учебные пособия и примеры EF и Code First моделирования, на которые я смотрел (например, от Scott Guthrie ), включают эти свойства, поэтому кажется неправильным не использовать их.
Итак, мой второй вопрос: Будут ли какие-либо недостатки и проблемы, которые я еще не обнаружил при выполнении этого?
Загрузите пример проекта здесь: http://blackfin.cannedtuna.org/cyclical-reference-test-app.zip, и откройте TestSolution.sln. Свойства закомментированы в примере проекта. Раскомментируйте строки в TestModels.cs, чтобы добавить свойства, что приведет к исключению циклической ссылки.
NB: Решение заключается в создании и заполнении базы данных SQL CE, расположенной по адресу c: \ TestApp.sdf
Обновление, декабрь 2011 г .:
Я никогда не решал эту проблему технически, но я бросил свою работу и нашел другую работу, где мне не нужно использовать технологии Microsoft. Такого рода решенная моя проблема:)
В качестве технической поддержки в старом месте, когда пишут при устранении проблем: «Обходной путь или решение предоставлено».