1
我有這樣的代碼:NHibernate的二級緩存不緩存整個實體
[TestFixture]
public class CachingTest
{
[Test]
public void Caches_second_request()
{
var sessionFactory = CreateSessionFactory();
int orderId;
{
var order = new Order {Created = DateTime.Now};
order.Rows.Add(new OrderRow {Price = 123, Order = order});
order.Rows.Add(new OrderRow { Price = 456, Order = order });
using (var session = sessionFactory.OpenSession())
{
session.Save(order);
orderId = order.Id;
}
}
Console.WriteLine("Saved");
using (var session = sessionFactory.OpenSession())
{
var order = session.Get<Order>(orderId);
Console.WriteLine(order.Rows.Count);
}
Console.WriteLine("Fetched first time");
using (var session = sessionFactory.OpenSession())
{
var order = session.Get<Order>(orderId);
Console.WriteLine(order.Rows.Count);
}
}
private static ISessionFactory CreateSessionFactory()
{
var autoMappingConfig = new AutoMappingConfiguration();
ISessionFactory sessionFactory = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008
.ConnectionString(c => c.FromAppSetting("connectionString"))
.ShowSql())
.Cache(c => c
.UseQueryCache()
.UseSecondLevelCache()
.ProviderClass<KamakuraCacheProvider>())
.Mappings(m =>
m.AutoMappings.Add(
AutoMap.AssemblyOf<CachingTest>(autoMappingConfig)
.Conventions.Add(
ForeignKey.EndsWith("Id"),
DefaultLazy.Never(),
DefaultCascade.All())
.Conventions.Add<CacheableConvention>()
))
.ExposeConfiguration(configuration =>
new SchemaExport(configuration).Create(false, true))
.BuildSessionFactory();
return sessionFactory;
}
}
public class CacheableConvention : IClassConventionAcceptance, IClassConvention
{
public void Accept(IAcceptanceCriteria<IClassInspector> criteria)
{
criteria.Expect(x => x.EntityType.IsAny(typeof (Order), typeof (OrderRow)));
}
public void Apply(IClassInstance instance)
{
instance.Cache.ReadWrite();
instance.Cache.IncludeAll();
}
}
public class AutoMappingConfiguration : DefaultAutomappingConfiguration
{
public override bool ShouldMap(Type type)
{
return type == typeof (Order) || type == typeof (OrderRow);
}
public override Access GetAccessStrategyForReadOnlyProperty(Member member)
{
return Access.ReadOnlyPropertyThroughCamelCaseField(CamelCasePrefix.Underscore);
}
}
public class Order
{
private readonly ICollection<OrderRow> _rows = new Collection<OrderRow>();
public virtual int Id { get; set; }
public virtual DateTime Created { get; set; }
public virtual ICollection<OrderRow> Rows
{
get { return _rows; }
}
}
public class OrderRow
{
public virtual int Id { get; set; }
public virtual Order Order { get; set; }
public virtual decimal Price { get; set; }
}
這會產生這樣的輸出:
NHibernate: INSERT INTO [Order] (Created) VALUES (@p0); select SCOPE_IDENTITY();@p0 = 2011-04-29 13:40:39 [Type: DateTime (0)]
NHibernate: INSERT INTO [OrderRow] (Price, OrderId) VALUES (@p0, @p1); select SCOPE_IDENTITY();@p0 = 123 [Type: Decimal (0)], @p1 = 1 [Type: Int32 (0)]
NHibernate: INSERT INTO [OrderRow] (Price, OrderId) VALUES (@p0, @p1); select SCOPE_IDENTITY();@p0 = 456 [Type: Decimal (0)], @p1 = 1 [Type: Int32 (0)]
Saved
NHibernate: SELECT order0_.Id as Id0_0_, order0_.Created as Created0_0_ FROM [Order] order0_ WHERE [email protected];@p0 = 1 [Type: Int32 (0)]
NHibernate: SELECT rows0_.OrderId as OrderId1_, rows0_.Id as Id1_, rows0_.Id as Id1_0_, rows0_.Price as Price1_0_, rows0_.OrderId as OrderId1_0_ FROM [OrderRow] rows0_ WHERE [email protected];@p0 = 1 [Type: Int32 (0)]
2
Fetched first time
NHibernate: SELECT rows0_.OrderId as OrderId1_, rows0_.Id as Id1_, rows0_.Id as Id1_0_, rows0_.Price as Price1_0_, rows0_.OrderId as OrderId1_0_ FROM [OrderRow] rows0_ WHERE [email protected];@p0 = 1 [Type: Int32 (0)]
2
我第二次使用的順序取Get方法,它不查詢Order表,但它仍然對OrderRow表進行查詢。
這可以通過某種方式進行配置,以便將它與訂單表數據一起緩存?
並設置取的集合映射做=「加盟」? – Vadim 2011-04-29 15:06:12