c# - NHibernate关于多对多关系的一些属性的搜索

标签 c# nhibernate many-to-many queryover

我有两个类ProductProductDetail(见下文)

我想在同一查询中对 Product 对象中的 CodeProductDetail 中的 Name 进行搜索。结果应该是一个Product列表。

我尝试过这个:

var search = "stringToSearch";
var list = _session.QueryOver<Product>()
    .Fetch(x => x.ProductDetails).Eager.Future<Product>()
    .Where(
        x => x.Code.StartsWith(search) || 
        x.ProductDetails.First().Name.StartsWith(search))
    .ToList();

当搜索与 Code 属性以及 ProductDetail 第一个记录的 Name 匹配时,查询会给出正确的结果, 但我想搜索 ProductDetails 的所有记录。

我该怎么做?

谢谢

public class Product
{
    public virtual int Id { get; set; }
    public virtual string Code { get; set; }
    public virtual IList<ProductDetail> ProductDetails { get; set; }
}

public class ProductDetail
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual string Description { get; set; }
    public virtual IList<Product> ProductDetails { get; set; }
}

The mapping :
public class ProductMap : ClassMap<Product>
{
    public ProductMap()
    {
        Table("Product");
        Id(x => x.Id).GeneratedBy.Native();
        Map(x => x.Code).Length(20).Unique().Not.Nullable();
        HasManyToMany(x => x.ProductDetails)
           .Cascade.All()
           .Table("ProductsProductsDetails");
    }
}
public class ProductDetailMap : ClassMap<ProductDetail>
{
    public ProductDetailMap()
    {
        Table("ProductDetail");
        Id(x => x.Id).GeneratedBy.Native();
        Map(x => x.Name).Not.Nullable().Length(50);
        Map(x => x.Description).Length(200);
        HasManyToMany(x => x.Products)
            .Cascade.All()
            .Inverse()
            .Table("ProductsProductsDetails");
    }
}

最佳答案

要查询这两个实体,您只需将它们与别名连接起来,然后使用这些别名来查询属性

// alias definition
Product productAlias = null;
ProductDetail detailAlias = null;

var list = session.QueryOver<Product>(() => productAlias)
    .JoinAlias(() => productAlias.ProductDetails, () => detailAlias)
    .Where(() => productAlias.Code.StartsWith(search))
    .And(() => detailAlias.Name.StartsWith(search))
    .List();

遗憾的是,nHibernate 不允许在此语法中使用 string.StartsWith,因此您必须优化查询以使用 .WhereRestrictionOnIsLike > 像这样:

var list = session.QueryOver<Product>(() => productAlias)
    .JoinAlias(() => productAlias.ProductDetails, () => detailAlias)
    .WhereRestrictionOn(() => productAlias.Code).IsLike(search, MatchMode.Start)
    .AndRestrictionOn(() => detailAlias.Name).IsLike(search, MatchMode.Start)
    .List();

:编辑:刚刚发现您想要一个 OR 查询,为此,我们必须在Where 语句中结合限制,例如:

var listWithOr = session.QueryOver<Product>(() => productAlias)
   .JoinAlias(() => productAlias.ProductDetails, () => detailAlias)
   .Where(Restrictions.On(() => productAlias.Code).IsLike(search, MatchMode.Start)
        || Restrictions.On(() => detailAlias.Name).IsLike(search, MatchMode.Start))
   .List();

希望这有帮助

:编辑2: 上面的查询不会为您提供不同的结果,某些产品可能会在列表中多次出现,如果需要,您必须使其成为不同的结果...

可以使用简单的 NHibernate.Linq 语句实现相同的查询(具有不同的结果):

var list2 = session.Query<Product>()
            .Where(prod => prod.Code.StartsWith(search) ||
                prod.ProductDetails.Any(detail => detail.Name.StartsWith(search))
            );

关于c# - NHibernate关于多对多关系的一些属性的搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19207163/

相关文章:

c# - 如何生成唯一的 12 位数字?

c# - Java 和 C# 线程处理数据同步的方式有何不同?

database - 在构建应用程序时,您首先考虑数据库或对象吗?

laravel - 2 个带有数据透视表的模型,多对多关系

c# - 如何通过 Fluent API Entity Framework 定义多对多关系?

python - 查询多对多字段

c# - 跨回发控制值持久性

c# - 如何使用 LINQ 将行转换为列来旋转数据

nhibernate 连接 Release模式 : why does the documentation recommened using "after_transaction"?

asp.net-mvc - 如何用 NHibernate + asp.net mvc 处理这种并发场景?