C# 对于需要在持久化之前创建关系的实体插入,我的代码应该在哪里?
情境:我正在使用LinqToSql(可能被认为是不相关的)作为我的“持久化层”,并试图解决一些架构问题,即某些可疑的业务相关逻辑应该去哪里 场景:应用程序的用户创建一个新订单。这样做时,需要将产品密钥集合与该订单关联 我的第一次尝试是将所有这些jazz放在OrderService类中。然后,我尝试使用分部方法将其与我的DataContext合并:C# 对于需要在持久化之前创建关系的实体插入,我的代码应该在哪里?,c#,linq-to-sql,anemic-domain-model,C#,Linq To Sql,Anemic Domain Model,情境:我正在使用LinqToSql(可能被认为是不相关的)作为我的“持久化层”,并试图解决一些架构问题,即某些可疑的业务相关逻辑应该去哪里 场景:应用程序的用户创建一个新订单。这样做时,需要将产品密钥集合与该订单关联 我的第一次尝试是将所有这些jazz放在OrderService类中。然后,我尝试使用分部方法将其与我的DataContext合并: partial void InsertOrder(Order instance) { var productKeys = this.P
partial void InsertOrder(Order instance)
{
var productKeys = this.ProductKeys
.Where(x => x.DeleteDate == null && x.Order == null && !x.Issued)
.Take(instance.NumberOfProductKeys);
if (productKeys.Count() != instance.NumberOfProductKeys)
throw new NotSupportedException("There needs to be more product keys in the database.");
instance.ProductKeys.AddRange(productKeys);
this.ExecuteDynamicInsert(instance);
}
忽略这一事实(产品密钥从未实际与订单关联),我觉得这是从我的业务领域剥离逻辑,并将其推到我的“持久层”。我还考虑将其放入OrderService类中,但觉得它也只是从域实体中删除了逻辑,并生成了一个事务脚本。引入订单工厂只是绕过了这个问题:数据和逻辑再次分离
所以我的问题是:为了避免一个贫乏的领域模型,并且希望order除了作为一个美化的数据结构之外还能做些什么,有没有一种合适的方法将这个逻辑集成到我的领域模型中
我提出的最佳解决方案是将逻辑放入Order类,并验证它是否在验证挂钩中完成:
public partial class Order
{
public void AssociateWithProductKeys(WIIIPDataContext context)
{
var productKeys = context.ProductKeys
.Where(x => x.DeleteDate == null && !x.Issued && x.Order == null && x.ProductType == ProductType)
.Take(NumberOfProductKeys);
if (productKeys.Count() != NumberOfProductKeys)
throw new ValidationException("There needs to be more product keys in the database for product type: " + ProductType.Description);
ProductKeys.AddRange(productKeys);
foreach (ProductKey productKey in ProductKeys)
{
productKey.Issued = true;
}
}
partial void OnValidate(ChangeAction action)
{
if (action == ChangeAction.Insert)
{
if (ProductType.Id == 3 && ProductKeys.Count() != 1)
throw new ValidationException("Attempted to associated more than 1 product key with a CD version.");
if (ProductKeys.Count() != NumberOfProductKeys)
throw new ValidationException("Number of product keys doesn't match expected value");
}
}
}
消费代码看起来是这样的:
// The Unit of Work
using (var context = new MyDataContext())
{
...
order.AssociateWithProductKeys(context);
context.Orders.InsertOnSubmit(order);
context.SubmitChanges();
}
==2012年3月29日更新==
在使用LinqToSQL(和Web表单)时,我采用了命令/查询模式,不再使用LinqToSQL DataContext创建的实体作为到数据存储的映射。我所有的规则和未包含的规则都进入到命令对象中,使它们在某种程度上成为应用程序的真正核心。客户机将订单传递给业务逻辑层(BLL)。BLL调用DAL方法以获取n个产品密钥。DAL不实现逻辑,它只获取n个键。BLL然后对DAL提供的内容作出反应。如果有足够的键,BLL将这些键与订单关联并返回。如果没有足够的键,则BLL不会将键与顺序关联,并引发异常。然后,客户机根据逻辑层返回的内容向用户提供正确的UI消息 我同意你自己的评估,即DAL中不应存在逻辑。这意味着DAL方法可以从不同的用例场景中重用,我们不希望DAL做出任何决定,因为业务规则可能会改变,新的用例可能会出现
这有帮助吗?客户机将订单传递给业务逻辑层(BLL)。BLL调用DAL方法以获取n个产品密钥。DAL不实现逻辑,它只获取n个键。BLL然后对DAL提供的内容作出反应。如果有足够的键,BLL将这些键与订单关联并返回。如果没有足够的键,则BLL不会将键与顺序关联,并引发异常。然后,客户机根据逻辑层返回的内容向用户提供正确的UI消息 我同意你自己的评估,即DAL中不应存在逻辑。这意味着DAL方法可以从不同的用例场景中重用,我们不希望DAL做出任何决定,因为业务规则可能会改变,新的用例可能会出现 这有用吗 我正在使用LinqToSql(可能被认为是不相关的) 我根本不认为这是不相干的。< /P> 不管讨论LINQtoSQL是否是“真正的”ORM,我发现所有的ORM(特别是LINQtoSQL)都是非常规范的,它们希望您使用它们。坚持他们喜欢的模式,一切都很简单。根据自己的选择构建代码,你就有可能走向痛苦的世界 在本例中,LINQ to SQL在包含数据访问和逻辑(紧密耦合)时工作得最好。一旦你有一个非常小的项目以外的东西,这是一个糟糕的做法,会导致调试噩梦,但如果你试图打破数据访问和逻辑,你会遇到一些常见的问题 微软的建议是,
DataContext
应该是用于工作单元的短期对象。这种方法不能很好地工作,因为LINQtoSQL使用的是“附加的”/“分离的”模型。有几十个网站提出“通过序列化分离”的攻击,在我看来,这是可怕的
此外,ORM模型适用于数据对象,而不是功能齐全的封装对象。DataContext
需要维护对象之间的关系,因此让它们自己负责往往会导致以后的麻烦
虽然我喜欢LINQtoSQL,并在许多项目中使用过它,但我不能推荐一个好的模式,我会积极推荐在数据级别上反对任何面向对象的模式。忘记你所知道的,试着编写一个易于维护的数据层。根据我的经验,基于严格的设计规则分离逻辑和数据访问将导致以后使用此工具包时出现重大问题
我正在使用LinqToSql(可能被认为是不相关的)
我根本不认为这是不相干的。< /P>
不管讨论LINQtoSQL是否是“真正的”ORM,我发现所有的ORM(特别是LINQtoSQL)都是非常规范的,它们希望您使用它们。坚持他们喜欢的模式,一切都很简单。根据自己的选择构建代码,你就有可能走向痛苦的世界
在本例中,LINQ to SQL在包含数据访问和逻辑(紧密耦合)时工作得最好。这是一个可怕的做法,一旦你有一个非常小的项目以外的任何东西,将导致调试噩梦,但如果你试图br