2012-03-02 3 views
1

私は別のテーブルとの関係を持つクラスを持っています。初心者のEF4.3とMVC4の関係

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

    public virtual OtherClass OtherClass { get; set; } 
} 

これをコントローラに接続し、CRUDのビューを作成します。すべて正常に動作します。

DBでは、OtherClass_OtherClassId列が作成されますが、これはモデルにはありません。

コントローラのCreateメソッドでこのId列に参照を挿入するにはどうすればよいですか?

毎回新しいOtherClassを作成する必要なく、この関係を強制的に[必須]にすることはできますか?

答えて

3

注釈付きクラス:

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; } 
} 

だから、良いですか? Independent associationsまたはforiegnキーを宣言していますか?

独立した関連付けは、オブジェクトプログラミングに近い一致性を示します。 OOPでは、1つのオブジェクトはメンバーのIDについて本当に気にしません。 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(); 

、あなたはそれが、エンティティの検証やattach a stubbed entity (assuming you know the id)ために必要ですので、だけでなく、データベースから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. 

-

独立した団体

  • グッド:マッチOOPとPOCOのより良い
  • 悪い:オブジェクトグラフを更新するだけで、完全なオブジェクトグラフが必要なことがよくあります。 2つの特性。より多くのEFの頭痛。

外部キー

  • グッド:時々で動作するように簡単 - レスEF頭痛。
  • 悪い:あなたのPOCOの
+0

おかげで、データベースへの懸念:そのオブジェクトと同期して

  • 悪いことができます。以前はEFをデータベースとして使用していましたが、最初にコードを書くのは初めてです。私は最終結果がかなり違うことに驚いています。あなたはDBの最初のこの問題を取得しません。 – simon831

  • 0

    EFは、一般的に、モデル構成でハンドホールドが必要です。これはあなたを始めるはずです。しかし、EFコードファーストとDBの最初の良いチュートリアルを行うことは非常に有益です。

    続いていますアイデンティティOrderTypeIdと実際のOrderTypeのRefオブジェクトを維持することによって作られた複数のOrderItems

  • シングルユーザー
  • とシングルOrderTypeと

    • 注文。

      パブリッククラスオーダー {治安(){ の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 {パブリック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 {保護オーバーライドボイドOnModelCreating(DbModelBuilder ModelBuilderの) {modelBuilder.Configurations.Add(新しいOrderConfiguration())。いくつかの説明と }} 「