nhibernate joinalias不构建正确的查询

时间:2013-11-15 23:52:52

标签: c# sql nhibernate fluent-nhibernate

每当我尝试执行此查询(QueryOver)时,我都会得到SqlException (The multi-part identifier "packageali1_.PackageID" could not be bound.)

var brandsFromBrandsInManufacturer2 =
  session.QueryOver<Brand>(() => brandAlias)
    .JoinAlias(brand => brand.Package, () => packageAlias)
    .Where(
       brand =>
       brand.ArtificialBrand == 0
     )
    .And(brand => packageAlias.PackageID
       .IsIn(branchPackagesProductGroupShortName.Keys))
    .Select(brand => brand.BrandName,
       brand => packageAlias.PackageID)
    List<object[]>();

看起来我的映射中有错误:

public class PackageMap : ClassMap<Package>
{
    public PackageMap()
    {
        Table("Packages");
        Id(x => x.PackageID).GeneratedBy.Identity();
        Map(x => x.Aggregated).CustomType<PackageAggregation>();
        References(x => x.DataEndPeriod, "DataEndPeriodID");
        References(x => x.Country, "CountryID");
        References(x => x.ProductGroup, "ProductGroupID");

        HasMany(x => x.PackageHierarchies).KeyColumns.Add("PackageId");
        HasMany(x => x.Brands).KeyColumns.Add("PackageId").Inverse();
    } 
}


public BrandMap()
    {
        Table("Brands");
        CompositeId().KeyProperty(x =>x.BrandId).KeyReference(x => x.Package, "PackageId");
        Map(x => x.BrandName);
        References(x => x.Manufacturer).Columns(x => x.ManufacturerId).Nullable();
        Map(x => x.ArtificialBrand);
    }

但我找不到有什么不对。我发现的唯一事实是,Brand具有经典ID密钥,但Package具有复合密钥。

PS:来自nHibernate的SQL查询是:

 SELECT this_.BrandName as y0_, packageali1_.PackageID as y1_ FROM CD.Brands this_ WHERE this_.ArtificialBrand = @p0 and packageali1_.PackageID in (...)

所以你可以看到,没有JOIN。

有人能指出我出了什么问题吗?

1 个答案:

答案 0 :(得分:0)

这里的解决方案是直接使用Key属性Package“工作”,而不是其别名。因此,让我们直接浏览packageAlias.PackageID

,而不是brand.Package.PackageID

另外,如果我们创建了这么多别名,那就让我们使用它们

var brandsFromBrandsInManufacturer2 = session
    .QueryOver<Brand>(() => brandAlias)
    .JoinAlias(() => brandAlias.Package, () => packageAlias) // use brandAlias
    .Where(() => brandAlias.ArtificialBrand == 0 )
    // no go to Package directly, not via packageAlias
    .And(() => brandAlias.Package.PackageID
       .IsIn(branchPackagesProductGroupShortName.Keys))
    // the same here, the brand.Package...
    .Select(brand => brand.BrandName,
       brand => brand.Package.PackageID)
    List<object[]>();

嗯,第二行实际上是多余的。所以它可能是这样的:

var list = session
    .QueryOver<Brand>(() => brandAlias)
    .Where(() => brandAlias.ArtificialBrand == 0 )
    .And(() => brandAlias.Package.PackageID
       .IsIn(branchPackagesProductGroupShortName.Keys))
    .Select(brand => brand.BrandName,
            brand => brand.Package.PackageID)
    List<object[]>();