我偶然发现在LINQ查询中使用我的规范.麻烦在于我的规范与params.
让我们假设一个简单的场景:
public class Car {
public Guid Id { get; set; }
public string Color { get; set; }
public int UsedPieces { get; set; }
// whatever properties
}
public class Piece {
public Guid Id { get; set; }
public string Color { get; set; }
// whatever properties
}
public static class PieceSpecifications : ISpecification<Piece> {
public static ISpecification<Piece> WithColor(string color) {
return new Specification<Piece>(p => p.Color == color);
}
}
Run Code Online (Sandbox Code Playgroud)
我真正想做的事情
// Get accepts ISpecification …Run Code Online (Sandbox Code Playgroud) 好的,我们必须计算疯狂复杂的保险注册数据的资格和费率。可以根据年龄,就业特点,鞋码等来制定政策。1962年之前出生的人可能会被排除在外,除非他们居住在德克萨斯州并且有贵宾犬等。
因此,我们可以构建实现规范模式的类。我们可以嵌套和指定,或指定等等。这太好了。但是现在我们如何将其序列化到数据库?
我们可以将c#类转储到xml并保留在那。但这很脆弱,但几乎无法查询。将类序列化为xml并将其转储到大文本字段中具有一定的代码味道。
关于如何将嵌套的规范放入数据库中,是否有规范的答案?我的Google Fu使我失望。
我正在尝试一起实现一个通用的规范模式和一个通用的访问者模式。这是我的基本接口。
export interface Specification<T, TVisitor extends SpecificationVisitor<TVisitor, T>> {
accept(visitor: TVisitor): void;
isSatisfiedBy(candidate: T): boolean;
and(other: Specification<T, TVisitor>): Specification<T, TVisitor>;
andNot(other: Specification<T, TVisitor>): Specification<T, TVisitor>;
or(other: Specification<T, TVisitor>): Specification<T, TVisitor>;
orNot(other: Specification<T, TVisitor>): Specification<T, TVisitor>;
not(): Specification<T, TVisitor>;
}
export interface SpecificationVisitor<TVisitor extends SpecificationVisitor<TVisitor, T>, T> {
visit(specification: AndSpecification<T, TVisitor>): void;
visit(specification: AndNotSpecification<T, TVisitor>): void;
visit(specification: OrSpecification<T, TVisitor>): void;
visit(specification: OrNotSpecification<T, TVisitor>): void;
visit(specification: NotSpecification<T, TVisitor>): void;
}
Run Code Online (Sandbox Code Playgroud)
为方便起见,我为基本布尔运算符实现了一些基类和一个抽象类。
export abstract class CompositeSpecification<T, TVisitor extends SpecificationVisitor<TVisitor, T>> implements Specification<T, TVisitor> …Run Code Online (Sandbox Code Playgroud) generics types visitor-pattern specification-pattern typescript
我有一个具有以下方法的存储库:
IEnumerable<T> FindAll<TRelated>(Specification<T> specification,
Expression<Func<T, TRelated>> fetchExpression);
Run Code Online (Sandbox Code Playgroud)
我需要传递多个表达式。我正在考虑将签名更改为:
IEnumerable<T> FindAll<TRelated>(Specification<T> specification,
IEnumerable<Expression<Func<T, TRelated>>> fetchExpression);
Run Code Online (Sandbox Code Playgroud)
目前我正在从服务层调用该方法,如下所示:
var products = productRepository.FindAll(specification,p => p.Variants);
Run Code Online (Sandbox Code Playgroud)
但我想通过p => p.Variants,p => p.Reviews例如。然后在存储库中,我想迭代表达式并将它们添加到查询中。
有关我为什么这样做的一些背景信息,请参阅 Ben Foster 的有关使用 NHibernate 进行预加载的博客文章。
linq specification-pattern linq-to-nhibernate linq-expressions
我想最近在git上传我的dotnetnuke网站,现在我的网站有一些图像,我不想通过git上传.
我在GIT上搜索并遇到了在存储库创建期间创建的.gitignore文件,GIT有一个关于忽略文件/文件夹及其特定子文件夹的文档,但它似乎在我的情况下不起作用.
这是我的文件夹结构:
*******更新*******.gitignore
public_html/Portals/_default/
public_html/Portals/0/
public_html/Portals/1/
public_html/Portals/110/
Run Code Online (Sandbox Code Playgroud)
现在我想忽略Portals下的所有文件夹,除了Portals/_default.我试过基于GIT的规范:
Example to exclude everything except a specific directory foo/bar (note the /* - without the slash, the wildcard would also exclude everything within foo/bar):
$ cat .gitignore
# exclude everything except directory foo/bar
/*
!/foo
/foo/*
!/foo/bar
Run Code Online (Sandbox Code Playgroud)
以下是我试过的:
!/Portals
/Portals/*
!/Portals/_default
Run Code Online (Sandbox Code Playgroud)
但这似乎根本不起作用.
谁能让我朝着正确的方向前进
我知道规范模式描述了如何使用实现类的层次结构ISpecification<T>来评估 T 类型的候选对象是否匹配某个规范(= 满足业务规则)。
我的问题:我要实现的业务规则需要评估多个对象(例如,客户和合同)。
我的双重问题:
是否有规范模式的典型改编来实现这一点?我只能考虑删除ISpecification<T>我的规范类的实现,并在isSatisfiedBy()方法中采用尽可能多的参数。但是通过这样做,我失去了将这个规范与其他规范结合起来的能力。
这个问题是否表明我的设计存在缺陷?(即我需要使用 Customer 来评估什么,而应该在另一个对象上评估合同,比如订阅,它可以包含所有必要的信息)?
我已经阅读了规范模式的一些示例,但很难理解如何使用此模式实现.
我正在为客户开发一个庞大的程序.我需要从特定的银行导入XML文件,然后对每个文件进行验证.分类帐代码有不同的方法(subs,bo,rcc).因此,当文件读取SUBS时,它应该发送到SUBS方法.
这里的例子:
接口:
分类帐代码:
结果:
你能给出一些示例代码或指出我正确的方向吗?
我使用spring数据和JpaSpecificationExecutor::findAll方法来获取模型。调用此方法时如何使用查询提示?
上面的源代码工作正常,但是我无法为我的JPA提供程序(在我的情况下为EclipseLink)设置QueryHint。
@Repository
public interface ProductRepository extends JpaRepository<Product, Integer>, JpaSpecificationExecutor<Product> {
}
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
public List<Product> findByTitle(String locale, String titleToSearch) {
return productRepository.findAll((Root<ProductCategory> root, CriteriaQuery<?> query, CriteriaBuilder builder) -> {
return builder.equal(builder.function("jsonb_extract_path_text", String.class, root.<String>get("title"), builder.literal(locale)), titleToSearch);
});
}
}
Run Code Online (Sandbox Code Playgroud)
以上是我使用spring-data使用查询提示的方式,
@Repository
public interface ProductRepository extends JpaRepository<Product, Integer>, JpaSpecificationExecutor<Product> {
@QueryHints(value = {
@QueryHint(name = org.eclipse.persistence.config.QueryHints.BATCH_TYPE, value = "JOIN"),
@QueryHint(name = org.eclipse.persistence.config.QueryHints.BATCH, value = "p.productCategory"),
@QueryHint(name = org.eclipse.persistence.config.QueryHints.BATCH, value = "p.productFileList")
}, …Run Code Online (Sandbox Code Playgroud) 我想问在遵循领域驱动设计理念和干净架构的项目中使用存储库工作单元是否有意义,或者它没有更有意义并且通用存储库模式就足够了?
domain-driven-design unit-of-work specification-pattern clean-architecture
我想编写一些API来使用LINQ2Entities对服务器端的实体(SQLServer)进行排序.
我有包含表达式的类表示实体的排序字段和排序方向:
public class SortOption<TEntity>
{
public SortOption(Expression<Func<TEntity, dynamic>> keySelector,
bool ascending = true)
{
KeySelector = keySelector;
Ascending = ascending;
}
public Expression<Func<TEntity, dynamic>> KeySelector { get; private set; }
public bool Ascending { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)
对于我的每个实体,我都有从上面继承的类.例如:
public class PostSorting: SortOption<PostEntity>
{
public PostSorting(): base(p => p.Published)
{
}
}
public class PostEntity
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public DateTime? Published { get; set; }
public DateTime Modified { get; set; } …Run Code Online (Sandbox Code Playgroud) c# sorting linq-to-entities entity-framework specification-pattern
我写了两个规范,如果它们的参数为 null,则返回 null。
public static Specification<Prodotto> getProdottoByLineaSpec (String linea) {
if (linea != null) {
return (root, query, criteriaBuilder) -> {
return criteriaBuilder.like((root.join("linea")).get("nome"), "%"+linea+"%");
};
}
else return null;
}
public static Specification<Prodotto> getProdottoByIngSpec (String ing) {
if (ing != null) {
return (root, query, criteriaBuilder) -> {
return criteriaBuilder.like(((root.join("listaQuoteIng")).join("ing")).get("nome"), "%"+ing+"%");
};
}
else return null;
}
Run Code Online (Sandbox Code Playgroud)
然后我创建了第三个,将前一个与子句中的and运算符结合起来where:
public static Specification<Prodotto> getProdottoByMainTraits (String linea, String ing) {
return Specification.where(getProdottoByLineaSpec(linea).and(getProdottoByIngSpec(ing)));
}
Run Code Online (Sandbox Code Playgroud)
现在,这是有趣的部分:
ByLinea回报null,我得到一个 …最近遇到一篇文章实现查询规范模式,我对将规范模式与通用存储库一起使用感到困惑。
我已经有一个像这样的通用回购协议:
public interface IGenericRepository<T> where T:class
{
IReadOnlyList<T> GetAllAsunc(int id);
IReadOnlyList<T> FindAsync(Expression<Func<T, bool>> filter);
T GetById(int id)
void Add(T item);
void Update(T item);
void Delete(T item);
}
Run Code Online (Sandbox Code Playgroud)
以及规范模式的示例方法
public BaseSpecification(Expression<Func<T, bool>> criteria)
{
Criteria = criteria;
}
Run Code Online (Sandbox Code Playgroud)
我可以用IReadOnlyList<T> FindAsync(Expression<Func<T, bool>> filter);方法发送任何表达式。所以,我真的不明白为什么我需要带有通用存储库的规范模式。看起来他们在做同样的事情。你能澄清一下吗?
c# design-patterns entity-framework specification-pattern repository-pattern
c# ×6
linq ×2
eclipselink ×1
generics ×1
git ×1
github ×1
gitignore ×1
java ×1
jpa ×1
null ×1
sorting ×1
spring-data ×1
types ×1
typescript ×1
unit-of-work ×1