foxmuldercp
@foxmuldercp
Системный администратор, программист, фотограф

EntityFramework, Linq и очень хитрые сущности. Вопрос по правильному написанию методов CRUD в MVC

Есть несколько классов
// основной класс
public MainClass 
{
      public MainClassId { get; set; }
...
      // отношение один ко многим в FluentApi
      public virtual List<SecondClass> SecondClass { get; set; }
}

// список из некоторых свойств для основного обьекта
public SecondClass
{
     public SecondClassId {get; set; }
..
      // отношение один к одному
      [XmlIgnore, ForeignKey("ThirdClass")]
       public Guid ThirdClassId { get; set; }
       public virtual ThirdClass ThirdClass { get; set; }
}

// категория для SecondClass
public class ThirdClass
{
       public Guid ThirdClassId { get; set; }
....
}


Вопросы:
1. как правильно все таки прописать прямые и обратные связи (допустим, по конкретному Id в ThirdClass получить список из MainClass, где хотя бы один из элементов SecondClass имеет привязку к данному ThirdClass)

2. Как правильно в MVC это всё выдергивать в представление через Linq, (про View/Editor template представлений я в курсе)

3. Как обновлять через EF в БД полученную модель в Post методе Edit(MainClass mainclass) 4. Как корректно удалять сущность MainClass со всеми его связями из SecondaryClass, не трогая ThirdClass.

5. Как создавать сущность MainClass, но так, чтобы не создавались левые сущности ThirdClass (в данный момент в приложении периодически появляются, хотя я явно прохожу проверкой и этого быть не должно)

Сейчас у меня CRUD методы это костыли, код которых мне определённо не нравится, например код обновления - фактически удаляет старую сущность (предварительно удалив диапазон SecondClass из context'а) и записывает вместо неё новую сущность полученную из метода Post

Кстати, мастерам EF вопрос - подскажите хорошую статью/книгу/ еще что, где расписан материал по правильной работе с Linq, MS SQL, хитрыми сущностями
  • Вопрос задан
  • 4085 просмотров
Пригласить эксперта
Ответы на вопрос 1
@VanHelSeenG
Идем с начала:
Небольшие поправки по классу, чтобы было понятно, что и как должно быть на самом деле
// основной класс
public MainClass 
{
      public MainClassId { get; set; }
...
      // отношение один ко многим в FluentApi
     [InverseProperty("MainClassProp")] //обратная связь
      public virtual List<SecondClass> SecondClass { get; set; }
}

// список из некоторых свойств для основного обьекта
public SecondClass
{
     public SecondClassId {get; set; }
    [InversePropert("SecondClass")] //указываем на связь со списком
    public MainClass MainClassProp
..
      // отношение один к одному
      [XmlIgnore]
       public Guid ThirdClassId { get; set; }
       [ForeignKey("ThirdClass")] //правильно делать так - указываем на переменную, того же типа, что и ключевое в ThirdClass, для MainClass тоже можно сделать
       public virtual ThirdClass ThirdClass { get; set; }
}

// категория для SecondClass
public class ThirdClass
{
       public Guid ThirdClassId { get; set; }
....
}

Также про отношения можно почитать здесь, все очень подробно и на русском

По вопросам:
1.
db.MainClasses.Include(s => s.SecondClass).Where(cl => cl.SecondClass.Any(s => s.ThirdClassId == %что-то%);

(Для .Include() нужно подключить пространство имен using System.Data.Entity, он нужен, чтобы EF подгрузил сразу таблицу с SecondClasses)
2. Уже,думаю, ответ ясен, нужно просто дальше разобраться
3. Для такой такой задачи нужно настроить Каскадное удаление, к примеру
DataContext перегрузить метод
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//тут строится такая конструкция
modelBuilder.Entity<MainClass>().HasMany(m => m.SecondClass).WithRequired(s => s.MainClassProp).WIllCascadeOnDelete();
//а чтобы не удалялись Third class
modelBuilder.Entity<SecondClass>().HasOptional(или Required)(s => s.ThirdClass).WillCascadeOnDelete(false);
}

4(он же 5). Чтобы не создавались новые сущности ThirdClass, нужно явно указывать ссылку на ThirdClass, чтобы EF понял связь, то есть, заранее, нужно сделать выборку
var res = db.ThirdClasses.FirstOrDefault(t => t.ThirdClassId ==%giud%);
if (res != null)
secondClass.ThirdClass = res;


P.S. на самом деле на сайте мелкомягких кучу разных статей. А так, вот еще одна статья:
msdn.microsoft.com/ru-ru/data/jj591621.aspx
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы