1

私はストアド プロシージャから来て、データ アクセス レイヤーを手動で作成しています。Linq To SQL またはエンティティ フレームワークを通常の計画のどこに適合させるべきかを理解しようとしています。私は通常、DAL レイヤーからビジネス レイヤーを分離し、その間にリポジトリを使用します。

生成されたクラスを linq から sql に使用するか、部分クラスを使用してそれらを拡張するか、完全な分離を行い、生成された linq クラスを分離されたビジネス エンティティにマップするようです。私は別の事業体に偏っています。しかし、これは直感に反するようです。

私の最後のプロジェクトの 1 つは、DDD とエンティティ フレームワークを使用していました。オブジェクトを更新する必要がある場合、ビジネス エンティティをレピストーリー レイヤーに移動しました。これは、DAL レイヤーに移動するときにコンテキストを作成し、オブジェクトを再クエリします。値を更新して再発行します。

データ コンテキストが保存されておらず、更新する前にオブジェクトを取得するために追加のクエリが必要だったので、大きな点はわかりませんでした。通常、更新を行うだけです(同時実行性が問題にならない場合)

だから私の質問は次のようになります:

  1. linq to sql で生成されたクラスをビジネス エンティティに分離することは理にかなっていますか?
  2. データ コンテキストを保存する必要がありますか、それとも非現実的ですか?

お時間をいただきありがとうございます。私が理解していることを確認してください。いくつかの小さなプロジェクトでも理解しやすくなるため、通常は分離するのが好きです。

4

1 に答える 1

3

現在、Linq から Sql への自動生成されたコード ファイルを使用する代わりに、独自の Dto クラスと Datacontext を手動でロールしています。私のソリューション アーキテクチャ/モデリングの背景を示すために、"Contract" プロジェクトと "Dal" プロジェクトがあります。(「モデル」プロジェクトでもありますが、ここでは Dal のみに焦点を当てます)。独自の Dtos と Datacontext を手動で作成すると、すべてが大幅に小さくシンプルになります。ここでは、その方法の例をいくつか示します。

Dal の外部で Dto オブジェクトを返すことはありません。実際、それらを必ず内部として宣言します。それらを返す方法は、それらをインターフェイスとしてキャストすることです(インターフェイスは「コントラクト」レイヤーにあります)。「IPersonRetriever および IPersonSaver」インターフェースを実装する単純な「PersonRepository」を作成します。

契約:

public interface IPersonRetriever
{
     IPerson GetPersonById(Guid personId);
}

public interface IPersonSaver
{
     void SavePerson(IPerson person);
}

ダル:

    public class PersonRepository : IPersonSaver, IPersonRetriever
    {
        private string _connectionString;

        public PersonRepository(string connectionString)
        {
            _connectionString = connectionString;
        }

        IPerson IPersonRetriever.GetPersonById(Guid id)
        {
            using (var dc = new PersonDataContext(_connectionString))
            {
                return dc.PersonDtos.FirstOrDefault(p => p.PersonId == id);
            }
        }

        void IPersonSaver.SavePerson(IPerson person)
        {
            using (var dc = new PersonDataContext(_connectionString))
            {
                var personDto = new PersonDto
                {
                    Id = person.Id,
                    FirstName = person.FirstName,
                    Age = person.Age
                };

                dc.PersonDtos.InsertOnSubmit(personDto);
                dc.SubmitChanges();
            }
        }
    }

PersonDataContext:

    internal class PersonDataContext : System.Data.Linq.DataContext
    {
        static MappingSource _mappingSource = new AttributeMappingSource(); // necessary for pre-compiled linq queries in .Net 4.0+

        internal PersonDataContext(string connectionString) : base(connectionString, _mappingSource) { }

        internal Table<PersonDto> PersonDtos { get { return GetTable<PersonDto>(); } }
    }

    [Table(Name = "dbo.Persons")]
    internal class PersonDto : IPerson
    {
        [Column(Name = "PersonIdentityId", IsPrimaryKey = true, IsDbGenerated = false)]
        internal Guid Id { get; set; }

        [Column]
        internal string FirstName { get; set; }

        [Column]
        internal int Age { get; set; }

        #region IPerson implementation

        Guid IPerson.Id { get { return this.Id; } }
        string IPerson.FirstName { get { return this.FirstName; } }
        int IPerson.Age { get { return this.Age; } }

        #endregion
    }

すべての Dto プロパティに「Column」属性を追加する必要がありますが、気づいた場合は、インターフェイス上でフィールドを公開したいものと、実際のテーブル列に名前付きパラメーターを追加する必要はありません。この例では、データベース内の PersonId は「PersonIdentityId」として保存されていますが、インターフェースでフィールドに「Id」と表示させるだけにしたいのです。

それが私のDalレイヤーのやり方です。このレイヤーは、本当に馬鹿げているべきだと思います。CRUD (Create、Retrieve、Update、および Delete) 操作のためにのみ存在するという意味でばかげています。すべてのビジネス ロジックは、IPersonSaver インターフェイスと IPersonRetriever インターフェイスを使用して利用する「モデル」プロジェクトに組み込まれます。

お役に立てれば!

于 2011-03-28T19:08:25.310 に答える