我有两个类Product
和ProductDetail
(见下文)
我想在同一查询中对 Product
对象中的 Code
和 ProductDetail 中的
。结果应该是一个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
,因此您必须优化查询以使用 .WhereRestrictionOn
和 IsLike
> 像这样:
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/