2012-01-25 9 views
1

データベースに接続するためにエンティティフレームワークでコードを使用する2つのクラス(この例ではいずれにしても)があります。SQLクエリでEntity Frameworkを使用して外部キー接続を確立

私はこれらをコンテキストクラスで直接データベースに接続すると、外部キーの関係がうまく結びつき、顧客クラス内の連絡先のコレクションにアクセスできます。

class RemoteServerContext : DbContext 
{ 
    public DbSet<Customer> Customers { get; set; } 
    public DbSet<Contact> Contacts { get; set; } 
    ... 
} 

私の問題は、これらのデータベーステーブルがさまざまなシステムで使用されており、大量であることです。効率を上げるために、私はデフォルトの振る舞いを、テーブルに直接ではなく、ビュー(そしてストアドプロシージャも)を指すようにオーバーライドしました。

public IEnumerable<Customer> Customers() 
    { 
     return Database.SqlQuery<Customer>("SELECT * FROM vw_CustomerList"); 
    } 

    public IEnumerable<Contact> Contacts() 
    { 
     return Database.SqlQuery<Contact>("SELECT * FROM vw_ContactsList"); 
    } 

それぞれのビューで、私は外来キーフィールドCustomerIdとContactIdが含まれていることを確認しました。

私はこれを行うと、クラスの結合が失われているように見えます。オブジェクトのいずれかにドリルすると、他のオブジェクトを指し示す必要があります。私は、外部キーフィールドが指し示すべきものを設定しようとしましたが、これはいずれも助けにならないようです。

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Contact>().HasRequired(p => p.Customer) 
      .WithMany() 
      .HasForeignKey(k => k.CustomerId); 
    } 

デフォルト動作をオーバーライドするときに接続を確立する方法はありますか?

答えて

1

この場合、上書きはありません。あなたは

public DbSet<Customer> Customers { get; set; } 

を取り除き、

public IEnumerable<Customer> Customers() 
{ 
    return Database.SqlQuery<Customer>("SELECT * FROM vw_CustomerList"); 
} 

とそれを交換した場合、あなたは完全に動作を変更しました。最初のものはEFの実体と完全な力を使用します。 2番目はカスタムSQLを実行するヘルパーです。最初にエンティティが定義されていない場合、OnModelCreatingでは、マッピングされたエンティティとしてCustomerは使用されません。通常のクラスとして使用されます(マッピングされたエンティティのみが遅延読み込みなどの機能を使用できます)。

お客様の顧客はビューにマップされているため、以前の顧客クラスをテーブルで使用することはできません。あなたのビューが更新可能である

public DbSet<Customer> Customers { get; set; } 

ない限り、あなたは例外あなたがしようとするたびに取得します:あなたは、これはあなたが使用してもう一度試すことができたら

modelBuilder.Entity<Customer>().ToTable("vw_ContactsList"); // EF code fist has no view mapping 

:あなたは浮気EFによってビューにお客様のマッピングを定義する必要がありますこのセットの顧客を追加、更新、または削除する。ビューにマッピングされたCustomerContactの関係をマップした後、ナビゲーションプロパティがうまくいけばうまくいくはずです。

SqlQueryの問題は、どのように動作するかです。分離されたエンティティを返します。分離されたエンティティはコンテキストに接続されておらず、ナビゲーションプロパティの読み込みが遅延しません。各Customerインスタンスをコンテキストに手動でアタッチして、再度実行するには、DbSetが必要です。

+0

こんにちは、それは素晴らしいです。ありがとうございました。私はトランザクションのものを無効にすることを望んでいます:既存のストアドプロシージャのセットを使用して作成、編集、削除してください。助けてくれてありがとう – GrahamJRoy

+1

ストアドプロシージャの作成、編集、削除操作をオーバーライドする場合は、ストアドプロシージャのマッピングをサポートしていないため、最初にコードを使用することはできません。 EDMXを使用する必要があります。 –

+0

あなたはちょうど私がこれまでにしたこと以上のものを数週間で大量の問題にぶつかり、私を救った。とてもありがたい。 EDMXに切り替える – GrahamJRoy

関連する問題