gpt4 book ai didi

c# - 在规范中组合 C# 代码和数据库代码

转载 作者:太空狗 更新时间:2023-10-30 01:25:18 28 4
gpt4 key购买 nike

有时您需要定义一些业务规则,规范模式是一个有用的工具。例如:

public class CanBorrowBooksSpec : ISpecification<Customer>
{
public bool Satisfies(Customer customer)
{
return customer.HasLibraryCard
&& !customer.UnpaidFines.Any();
}
}

但是,我经常发现我需要将这些规则“推送”到 SQL 中以提高性能或满足分页记录列表之类的需求。

然后我不得不为规则编写代码两次,一次是在 CLR 代码中,一次是在 SQL(或 ORM 语言)中。

如何组织这样的代码?

最好将代码放在同一个类中。这样,如果开发人员正在更新业务规则,他们就不太可能忘记更新两组代码。例如:

public class CanBorrowBooksSpec : ISpecification<Customer>
{
public bool Satisfies(Customer customer)
{
return customer.HasLibraryCard
&& !customer.UnpaidFines.Any();
}

public void AddSql(StringBuilder sql)
{
sql.Append(@"customer.HasLibraryCard
AND NOT EXISTS (SELECT Id FROM CustomerUnpaidFines WHERE CustomerId = customer.Id)");
}
}

然而,这对我来说似乎很丑陋,因为我们现在将问题混合在一起。

另一种选择是使用 Linq-To-YourORM 解决方案,因为 LINQ 代码可以针对集合运行,也可以转换为 SQL。但我发现,除了最微不足道的场景外,这种解决方案几乎不可能实现。

你是做什么的?

最佳答案

我们在 Entity Framework 中使用了规范模式。这是我们的处理方式

public interface ISpecification<TEntity>
{
Expression<Func<TEntity, bool>> Predicate { get; }
}


public class CanBorrowBooksSpec : ISpecification<Customer>
{
Expression<Func<Customer, bool>> Predicate
{
get{ return customer => customer.HasLibraryCard
&& !customer.UnpaidFines.Any()}
}
}

然后您可以将它用于 LINQ-to-Entities,例如

db.Customers.Where(canBorrowBooksSpec.Predicate);

在 LINQ-to-Objects 中

customerCollection.Where(canBorrowBooksSpec.Predicate.Compile());

关于c# - 在规范中组合 C# 代码和数据库代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7200792/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com