2

生成された 2 つの異なる linq コードを使用する場合、Rob Conery が [MVC Storefront][1] で示しているいわゆる「リポジトリ パターン」を実装するにはどうすればよいですか? Fredrik Normen がWhat Purpose does the Repository Pattern has? で説明しているように、実際のリポジトリ パターンを実装する必要がありますか? ? 問題は、LINQ が提供する優れた機能のいくつかを「リポジトリ」から渡して、後で使用できるようにすることです。そのため、Fredrik が説明したように、必要でない場合は実際のリポジトリ パターンを実装したくありません。

今私の問題に。MySql、Oracle、PostgreSQL の Linq プロバイダーである [dblinq ][3] をダウンロードしました。私のプロジェクトでは、MySQL と SQL(microsoft) の 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

}
4

4 に答える 4

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 Designerを使用すると、テーブル/クラスプロパティで名前空間を指定するか、DBMLファイルを自分で編集することができます。

于 2009-08-27T17:18:56.257 に答える
0

私はあなたと同じ状況にあり、Linq-to-SQL を使用していますが、将来は Entity Framework を試してみたいと思っています。

私が見た限りでは、その解決策は依存性注入と ioc コンテナーを使用することです (使用していない場合は、見てください。難しいように思えるかもしれませんが、非常に簡単で興味深いものです)。

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

たとえば、ICustomersRepositoryコントローラで使用できる がSQLCustomersRepositoryありEntityCustomersRepository、構成ファイルを変更するだけで交換できる と があります。

あなたが言ったように、問題は同じ名前のエンティティです...解決策は、エンティティに同じパターンを使用し、各エンティティのインターフェイスを作成し、ioc コンテナーを使用することです。これは退屈だと思います。各エンティティのインターフェイスを自動的に作成する T4 テンプレートを作成し、それを実装するために LinqToSQL とエンティティ フレームワークを使用する T4 テンプレートを置き換えることです...はい、大変な作業です。

T4 の概要については、このビデオ ( http://msdn.microsoft.com/en-us/vstudio/cc308634.aspx ) をご覧ください。

于 2009-08-03T12:48:06.487 に答える