我来自存储过程并手动创建数据访问层。我试图了解我应该将Linq To SQL或实体框架放到我的正常计划中。我通常从DAL层分离出业务层,并在中间使用存储库。
似乎人们要么使用从linq生成的类到sql,使用partial类扩展它们,要么完全分离并将生成的linq类映射到单独的业务实体。我偏向于单独的商业实体。然而,这似乎违反直觉。
我最近的一个项目使用DDD和实体框架。当需要对对象进行udpate时,它将业务实体移动到repistory层,当进入DAL层时,它将创建一个上下文而不是重新查询该对象。它会比更新值和resbumit。
我没有看到大点,因为没有保存数据上下文,并且在更新之前需要额外的查询来获取对象。通常我会做更新(如果并发不是问题)
所以我的问题归结为:
感谢您的时间,努力确保我理解。我通常喜欢分开,因为即使在一些较小的项目中也能让它更清晰。
答案 0 :(得分:3)
我目前手动滚动我自己的Dto类和Datacontext,而不是使用从Linq到Sql的自动生成的代码文件。为了给出我的解决方案架构/建模的一些背景知识,我有一个“合同”项目和一个“Dal”项目。 (也是一个“模型”项目,但我会尽力专注于Dal)。手工制作我自己的Dtos和Datacontext,使一切变得更小更简单,我将举几个例子说明我是如何做到的。
我永远不会在Dal之外返回一个Dto对象,事实上我确保将它们声明为内部。我将它们退出的方式是将它们作为接口转换(接口位于我的“合同”层)。我们将创建一个简单的“PersonRepository”来实现“IPersonRetriever和IPersonSaver”接口。
合同:
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属性中,但是如果您注意到,如果您希望字段在界面上显示的内容之间存在一对一的关联,那么实际表列的名称,您不需要添加任何命名参数。在这个例子中,我的数据库中的PersonId存储为“PersonIdentityId”,但我只希望我的界面使该字段说“Id”。
这就是我如何做我的Dal层,我相信这层应该是愚蠢的,真正的愚蠢。愚蠢的意思是它只适用于CRUD(创建,检索,更新和删除)操作。所有业务逻辑都将进入我的“模型”项目,该项目将使用和利用IPersonSaver和IPersonRetriever接口。
希望这有帮助!