Новичок EF4.3 и MVC4 Отношения - PullRequest
1 голос
/ 02 марта 2012

У меня есть класс с отношением к другой таблице.

public class MyClass
{
    [Key]
    public Guid Id {get; set; }

    public virtual OtherClass OtherClass { get; set; }
}

Я подключаю это к контроллеру и создаю представления для CRUD - все работает отлично.

В БДСтолбец OtherClass_OtherClassId создан, но его нет в модели.

Как поместить ссылку в этот столбец Id во время метода Create контроллера?

Как заставить это отношение быть [Обязательно] без необходимости каждый раз создавать новый OtherClass?

Ответы [ 2 ]

3 голосов
/ 02 марта 2012

Аннотированный класс с некоторым описанием:

public class MyClass
{
    // [Key] - Don't actually need this attribute
    // EF Code First has a number of conventions.
    // Columns called "Id" are assumed to be the Key.
    public Guid Id {get; set; }

    // This reference creates an 'Independent Association'.  The Database
    // foreign key is created by convention and hidden away in the code.
    [Required]
    public virtual OtherClass OtherClass { get; set; }

    // This setup explicitly declares the foreign key property.
    // Again, by convention, EF assumes that "FooId" will be the key for
    // a reference to object "Foo"

    // This will still be required and a cascade-on-delete property
    // like above - an int? would make the association optional.
    public int OtherClass2Id { get; set; }

    // Leave the navigation property as this - no [Required]
    public virtual OtherClass2 { get; set; }
}

Так что лучше? Независимые ассоциации или объявление внешнего ключа?

Независимые ассоциации ближе соответствуют объектному программированию.С ООП один объект не особо заботится об идентификаторе члена.ORM пытается скрыть эти отношения с разной степенью успеха.

Объявление внешнего ключа ставит проблемы базы данных в вашу модель, но есть сценарии, в которых это значительно облегчает работу с EF.

Пример - при обновлении объекта требуемой независимой ассоциацией EF захочет иметь весь граф объектов на месте.

public class MyClass
{
    public int Id {get; set; }
    public string Name { get; set; }
    [Required]  // Note the required.  An optional won't have issues below.
    public virtual OtherClass OtherClass { get; set; }
}

var c = db.MyClasses.Find(1);
c.Name = "Bruce Wayne";

// Validation error on c.OtherClass.
// EF expects required associations to be loaded.
db.SaveChanges();  

Если все, что вы хотите сделать, это обновить имя, вам придется либотакже извлеките OtherClass из базы данных, поскольку он требуется для проверки сущности или присоедините заглушенный объект (при условии, что вы знаете идентификатор) .Если вы явно объявите внешний ключ, вы не столкнетесь с этим сценарием.

Теперь с внешними ключами вы столкнетесь с другой проблемой:

public class MyClass
{
    public Guid Id {get; set; }
    public string Name { get; set; }

    public int OtherClassId { get; set }
    public virtual OtherClass OtherClass { get; set; }
}

var c = db.MyClasses.Find(1);

// Stepping through dubugger, here, c.OtherClassId = old id

c.OtherClass = somethingElse;

// c.OtherClassId = old id - Object and id not synced!

db.SaveChanges();               

// c.OtherClassId = new id, association persists correctly though.

В итоге -

Независимые ассоциации

  • Хорошо: лучше сопоставлять ООП и POCO
  • Плохо: часто требуется полный граф объектов, даже если вы обновляете только одинили два свойства.Больше головных болей EF.

Иностранные ключи

  • Хорошо: иногда легче работать - меньше головных болей EF.
  • Плохо:Может быть не синхронизирован с их объектом
  • Плохо: проблемы с базой данных в вашем POCO
0 голосов
/ 02 марта 2012

EF обычно требует держателя в зависимости от конфигурации модели. Это должно начать вас. Однако было бы очень полезно сделать хорошее руководство по EF Code First и DB first.

Следующий имеет:

  • Заказ с несколькими OrderItems
  • один пользователь
  • и одиночный OrderType, созданный путем сохранения идентификатора OrderTypeId и фактического объекта ссылки OrderType.

    Публичный класс Order { общественный порядок() { OrderItems = новый OrderItemCollection (); }

    public int OrderID { get; set; }
    public DateTime OrderDate { get; set; }
    public string OrderName { get; set; }
    
    public int UserId { get; set; }
    public virtual User OrderUser { get; set; }
    
    public virtual OrderItemCollection OrderItems { get; set; }
    public int? OrderTypeId { get; set; }
    public OrderType OrderType { get; set; }
    public override int GetHashCode() { return OrderID.GetHashCode();}
    

    } открытый класс OrderConfiguration: EntityTypeConfiguration { public OrderConfiguration () { this.ToTable ( "ЗАКАЗЫ"); this.HasKey (p => p.OrderID); this.Property (x => x.OrderID) .HasColumnName ("ORDER_ID"); this.Property (x => x.OrderName) .HasMaxLength (200); this.HasMany (x => x.OrderItems) .WithOptional (). HasForeignKey (x => x.OrderID) .WillCascadeOnDelete (true);

        this.HasRequired(u => u.OrderUser).WithMany().HasForeignKey(u => u.UserId);
        this.Property(x => x.OrderTypeId).HasColumnName("ORDER_TYPE_ID");
        this.HasOptional(u => u.OrderType).WithMany().HasForeignKey(u => u.OrderTypeId);
    }
    

    } открытый класс OrderContext: DbContext { защищенное переопределение void OnModelCreating (DbModelBuilder modelBuilder) { modelBuilder.Configurations.Add (new OrderConfiguration ()); } } «

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...