2009-07-23 25 views
2

RobCon Coneryが[MVC Storefront] [1]で示した、いわゆる2つの異なるlinqコードを使用すると、いわゆる「リポジトリパターン」をどのように実装できますか? Fredrik Normenが議論しているように、実際のリポジトリパターンを実装する必要がありますか?What purpose does the Repository Pattern have??それは、LINQが私の "リポジトリ"から提供する素敵な機能の一部を私が後で使うことができるようにするためです。そうでない場合は、Fredrikが議論したように実際のリポジトリパターンを実装したくありません。linqを使用したリポジトリパターン

問題が発生しました。私はMySql、Oracle、PostgreSQLのLinqプロバイダである[dblinq] [3]をダウンロードしました。私のプロジェクトでは、MySQLとSQL(マイクロソフト)用のLINQコードを生成しました。問題は、同じ名前のクラスを生成する必要があることですが、コンテンツは多少異なります。どういうわけか、これをネームスペースや何かで実装して、どちらも使えるようにすることができますか?「リポジトリパターン」のアイデアですか? 例SQL

言語テーブルの
[Table(Name="dbo.Language")] 
public partial class Language : INotifyPropertyChanging, INotifyPropertyChanged 
{ 

    private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty); 

    private int _Id; 

    private string _Name; 

    private EntitySet<Book> _Books; 

#region Extensibility Method Definitions 
partial void OnLoaded(); 
partial void OnValidate(System.Data.Linq.ChangeAction action); 
partial void OnCreated(); 
partial void OnIdChanging(int value); 
partial void OnIdChanged(); 
partial void OnNameChanging(string value); 
partial void OnNameChanged(); 
#endregion 

    public Language() 
    { 
     this._Books = new EntitySet<Book>(new Action<Book>(this.attach_Books), new Action<Book>(this.detach_Books)); 
     OnCreated(); 
    } 

    [Column(Storage="_Id", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)] 
    public int Id 
    { 
     get 
     { 
      return this._Id; 
     } 
     set 
     { 
      if ((this._Id != value)) 
      { 
       this.OnIdChanging(value); 
       this.SendPropertyChanging(); 
       this._Id = value; 
       this.SendPropertyChanged("Id"); 
       this.OnIdChanged(); 
      } 
     } 
    } 

    [Column(Storage="_Name", DbType="NVarChar(100) NOT NULL", CanBeNull=false)] 
    public string Name 
    { 
     get 
     { 
      return this._Name; 
     } 
     set 
     { 
      if ((this._Name != value)) 
      { 
       this.OnNameChanging(value); 
       this.SendPropertyChanging(); 
       this._Name = value; 
       this.SendPropertyChanged("Name"); 
       this.OnNameChanged(); 
      } 
     } 
    } 

    [Association(Name="Language_Book", Storage="_Books", ThisKey="Id", OtherKey="Language")] 
    public EntitySet<Book> Books 
    { 
     get 
     { 
      return this._Books; 
     } 
     set 
     { 
      this._Books.Assign(value); 
     } 
    } 

    public event PropertyChangingEventHandler PropertyChanging; 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void SendPropertyChanging() 
    { 
     if ((this.PropertyChanging != null)) 
     { 
      this.PropertyChanging(this, emptyChangingEventArgs); 
     } 
    } 

    protected virtual void SendPropertyChanged(String propertyName) 
    { 
     if ((this.PropertyChanged != null)) 
     { 
      this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    private void attach_Books(Book entity) 
    { 
     this.SendPropertyChanging(); 
     entity.Language1 = this; 
    } 

    private void detach_Books(Book entity) 
    { 
     this.SendPropertyChanging(); 
     entity.Language1 = null; 
    } 
} 

MySQLの

[Table(Name = "asp.Language")] 
public partial class Language : INotifyPropertyChanged 
{ 
    #region INotifyPropertyChanged handling 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    #endregion 

    #region int ID 

    private int _id; 
    [DebuggerNonUserCode] 
    [Column(Storage = "_id", Name = "Id", DbType = "int", IsPrimaryKey = true, IsDbGenerated = true, CanBeNull = false)] 
    public int ID 
    { 
     get 
     { 
      return _id; 
     } 
     set 
     { 
      if (value != _id) 
      { 
       _id = value; 
       OnPropertyChanged("ID"); 
      } 
     } 
    } 

    #endregion 

    #region string Name 

    private string _name; 
    [DebuggerNonUserCode] 
    [Column(Storage = "_name", Name = "Name", DbType = "varchar(100)", CanBeNull = false)] 
    public string Name 
    { 
     get 
     { 
      return _name; 
     } 
     set 
     { 
      if (value != _name) 
      { 
       _name = value; 
       OnPropertyChanged("Name"); 
      } 
     } 
    } 

    #endregion 

    #region Children 

    private EntitySet<Book> _book; 
    [Association(Storage = "_book", OtherKey = "Language", ThisKey = "ID", Name = "Book_ibfk_1")] 
    [DebuggerNonUserCode] 
    public EntitySet<Book> Book 
    { 
     get 
     { 
      return _book; 
     } 
     set 
     { 
      _book = value; 
     } 
    } 


    #endregion 

    #region Attachement handlers 

    private void Book_Attach(Book entity) 
    { 
     entity.LanguageLanguage = this; 
    } 

    private void Book_Detach(Book entity) 
    { 
     entity.LanguageLanguage = null; 
    } 


    #endregion 

    #region ctor 

    public Language() 
    { 
     _book = new EntitySet<Book>(Book_Attach, Book_Detach); 
    } 

    #endregion 

} 

答えて

1

理想的には、各クラスを1回だけ作成し、データベースの相違点をORMで処理する必要があります(これがNHibernateとSubsonicの仕組みです)。

実際にデータベースごとに異なるクラスが必要な場合は、は異なる名前空間にある限り同じ名前のクラスを持つことができます。あなたはクラスのコードを自分で書いている場合、これは非常に簡単です:

// C# sample 
namespace MyCompany.MyApp.Entities.Oracle 
{ 
    public class MyClass 
    { 
    // ... 
    } 
} 

namespace MyCompany.MyApp.Entities.SqlServer 
{ 
    public class MyClass 
    { 
    // ... 
    } 
} 

クラスが自動生成されている場合は、名前空間を指定する方法のコード生成ツールでチェックする必要があります。たとえば、LINQ to SQLデザイナでは、テーブル/クラスのプロパティで名前空間を指定するか、DBMLファイルを自分で編集します。

1

これは少しofftopicですが、それは役立つかもしれません。

Linq、リポジトリ、MySql、MS Sql、Rob Conneryのアドバイスを使用している場合は、SubSonic 3を使用して、あなたの人生を少し楽にするかもしれません。ここで

は、5分間のデモです:http://subsonicproject.com/docs/Simple_Repo_5_Minute_Demo

+0

ありがとうございました。 SubSonicは確かに有望に見えます。しかし、私はそのようなものを使用し始める前に.netについてもっと学びたいと思っています(私はちょうど.netを今一週間試しました)。 – unkownt

0

あなたは、私はLINQのツーSQLを使用していますが、将来的には、私はEntity Frameworkのを試してみたい、と私はやるだろうと私は同じような状況にしています。

私が見たところでは、その使用の依存性注入とiocコンテナ(あなたがそれを使用していない場合は見て、難しいかもしれないが、非常に簡単で興味深い)の解決策です。

ほとんどの例では、各リポジトリのインタフェースを作成し、ioc構成ファイルを使用して、使用するものを選択できます。

たとえば、コントローラーで使用する可能性があるのはICustomersRepository、構成ファイルの変更のみを交換できるのはSQLCustomersRepositoryEntityCustomersRepositoryです。

問題は、同じ名前のエンティティであると言いました。解決策は、エンティティに同じパターンを使用し、各エンティティのインタフェースを作成し、iocコンテナを使用することです。私はこれがtediusであることを知っています。私はT4テンプレートを作成して各エンティティのインターフェイスを自動的に作成し、次にLinqToSQLとentiy Frameworkを実装するT4テンプレートを置き換えます。 T4の導入のための

は、 http://msdn.microsoft.com/en-us/vstudio/cc308634.aspx

0

をこのビデオを見て私はそのようなMyCompany.MyApp.Entitiesとして、あなたのBOのためのエンティティの名前空間をお勧めします。

これで、各DBMLのEntity Namespaceプロパティを変更して、この中のエンティティを生成できます。同じタイプのDBMLを複数使用している場合は、DBMLごとにMyCompany.MyApp.Entitiesなどの別々の名前空間が必要です。

複数のデータベース/データアクセスプラットフォームのクラスを必要とする場合は、エンティティが具体化できる抽象基本クラスを作成し、データアクセスを行う抽象リポジトリを作成することをお勧めします。

自分の経験上、私は最近、抽象的なLinqToSqlRepostoryを作成し、これを主なビジネスオブジェクト用に拡張しました。

関連する問題