如何为关联配置Fluent NHibernate显式左/内连接&

时间:2013-06-14 11:30:39

标签: c# .net nhibernate fluent-nhibernate

首先,一些代码来解释我的配置:

public class OrdersSessionFactoryCreator
    : ISessionFactoryCreator
{
    public NHibernate.ISessionFactory Create()
    {
        var ret =
            Fluently
                .Configure()
                .Database(MsSqlConfiguration
                    .MsSql2008
                    .DoNot.UseOuterJoin()
                    .UseReflectionOptimizer()
                    .ShowSql()
                    .FormatSql()
                    .ConnectionString(ex =>
                        ex.FromConnectionStringWithKey("OrdersSqlServer")))
                .Mappings(
                    x =>
                        x.AutoMappings.Add(
                            AutoMap.AssemblyOf<Order>(new AutoConfig()).UseOverridesFromAssemblyOf<Order>()
                                .Conventions.Add<DefaultStringLengthConvention>()
                                .Conventions.Add(DefaultCascade.None())))
                .ExposeConfiguration(config => new SchemaExport(config).Create(true, true))
                .BuildSessionFactory();

        return ret;
    }
}

现在,域模型:

public class Order : EntityBase
{
    public Order(Guid id)
        : base(id)
    {
    }

    protected Order()
    {
    }

    public virtual Customer Customer { get; set; }
}

public class Customer : EntityBase
{
    public Customer(Guid id)
        : base(id)
    {
    }
    protected Customer()
    {
    }

    public virtual IList<Order> Orders { get; set; }
}

public class OrderMap : IAutoMappingOverride<Order>
{
    public void Override(AutoMapping<Order> mapping)
    {
        //mapping.HasOne(c => c.Customer).Not.LazyLoad().Cascade.All();
        mapping.References(c => c.Customer).Not.Nullable();
    }
}

public class CustomerMap : IAutoMappingOverride<Customer>
{
    public void Override(AutoMapping<Customer> mapping)
    {
        mapping.HasMany(o => o.Orders).Cascade.All().Fetch.Join();
    }
}

现在,如果我这样查询:

var orders = session.Query<Customer>().SelectMany(c => c.Orders).ToArray();

我的客户得到了适当的内部联系。但如果我从另一边做同样的事情:

var or = session.Query<Order>().Select(c => c.Customer).ToArray();

我得到一个LEFT JOIN,可以在大数据上造成严重的性能下降。

问题是:有没有办法指示NH使用INNER JOIN用于我所有不可空的参考列,所以我没有被迫使用QueryOver

2 个答案:

答案 0 :(得分:0)

您是否尝试过真正的加入

var ordersWithCustomers = 
   from o in Session.Query<Order>()
   join c in Session.Query<Customer>() on o.Customer.Id equals c.Id
   select o;

return ordersWithCustomers.ToArray();

(有趣的是,LINQ to NH从未支持左连接,QueryOver撼动IMHO)。

答案 1 :(得分:0)

您可以在OrderMap中尝试Cascade.All():IAutoMappingOverride