現在、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 インターフェイスを使用して利用する「モデル」プロジェクトに組み込まれます。
お役に立てれば!