Я уже несколько дней пытаюсь решить эту проблему. Создавая простой проект, иллюстрирующий мою проблему, я наткнулся на возможное решение. Так что это своего рода двойной вопрос.
Но сначала небольшая справочная информация:
Я только начал использовать 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 Fathers { get; set; }
public virtual ICollection Mothers { get; set; }
}
public class Mother
{
public int ID { get; set; }
public string Name { get; set; }
public int FamilyID { get; set; }
public virtual ICollection 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 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 Families { get; set; }
public DbSet Mothers { get; set; }
public DbSet Fathers { get; set; }
public DbSet Children { get; set; }
}
}
(Прошу простить неудачный пример, это то, что смог придумать мой пятничный жареный мозг.)
В семье может быть несколько матерей и несколько отцы. А у ребенка есть мать и отец. Я поработал с одним из гуру .NET, который согласился, что в этом нет ничего экстраординарного. По крайней мере, насколько мы можем видеть.
Но когда я запускаю код, я получаю следующее исключение:
System.Data.SqlServerCe.SqlCeException: ссылочная связь приведет к циклической ссылке, которая недопустима. [Constraint name = Mother_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 Fathers { get; set; }
public virtual ICollection Mothers { get; set; }
}
public class Mother
{
public int ID { get; set; }
public string Name { get; set; }
// public int FamilyID { get; set; }
public virtual ICollection 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 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, на которые я смотрел (например, , это Скотт Гатри ), включают эти свойства, поэтому я считаю неправильным не использовать их.
Итак, мой второй вопрос: Будут ли какие-то недостатки и проблемы, которые я еще не обнаружил при этом?
Загрузите пример проекта здесь: http://blackfin.cannedtuna.org/cyclical-reference-test -app.zip и откройте TestSolution.sln. В примере проекта свойства закомментированы. Раскомментируйте строки в TestModels.cs, чтобы добавить свойства, что приведет к исключению циклической ссылки.
NB: Решение создает и заполняет базу данных SQL CE, расположенную в c: \ TestApp.sdf
Update, Декабрь 2011 г .: Технически я эту проблему так и не решил, но бросил работу и нашел другую работу, где мне не нужно использовать технологии Microsoft. Такого рода решена моя проблема :)
Как служба техподдержки на старом месте писала при устранении проблем: «Был предоставлен обходной путь или решение».