好的,这是一个相当令人沮丧的经历:)我正在尝试使用基于接口的域模型,我可以获得ALMOST所有工作,但实际保存数据的能力除外
这是我到目前为止所拥有的。
public interface IEntity {
Guid Id {get;set;}
}
public interface IProduct : IEntity {
string Name {get;set;}
string SKU {get;set;}
decimal MSRP {get;set;}
}
public class Product : IProduct {
public virtual Guid Id {get;set;}
public virtual string Name {get;set;}
public virtual string SKU {get;set;}
public virtual decimal MSRP {get;set;}
}
public interface IOrder : IEntity {
DateTime CreatedOn {get;set;}
IList<IOrderLine> Lines {get;set;}
}
public class Order : IOrder {
public virtual Guid Id {get;set;}
public virtual DateTime CreatedOn {get;set;}
public virtual IList<IOrderLine> Lines {get;set;}
}
public interface IOrderLine : IEntity {
IProduct Product {get;set;}
int Qty {get;set;}
decimal Price {get;set;}
}
public class OrderLine : IOrderLine {
public virtual Guid Id {get;set;}
public virtual IProduct Product {get;set;}
public virtual int Qty {get;set;}
public virtual decimal Price {get;set;}
}
public class ProductMap : ClassMap<IProduct>
{
public ProductMap() {
Id(x => x.Id);
Map(x => x.Name);
Map(x => x.SKU);
Map(x => x.MSRP);
}
}
public class OrderMap : ClassMap<IOrder>
{
public OrderMap() {
Id(x => x.Id);
Map(x => x.CreatedOn);
HasMany(x => x.Lines)
.KeyColumns.Add("Id");
}
}
public class OrderLineMap : ClassMap<IOrderLine>
{
public OrderLineMap() {
Id(x => x.Id);
Map(x => x.Qty);
Map(x => x.Price);
References(x => x.Product)
.PropertyRef(x => x.Id)
.ForeignKey("productId");
}
}
public static class NHibernateUtils
{
public static ISessionFactory CreateSessionFactory(IPersistenceConfigurer persistenceConfigurer)
{
return Fluently.Configure()
.Database(persistenceConfigurer)
.Mappings(m =>
{
m.FluentMappings.Add<ProductMap>();
m.FluentMappings.Add<OrderLineMap>();
m.FluentMappings.Add<OrderMap>();
})
.ExposeConfiguration(c => new SchemaExport(c).Create(false, true))
.BuildConfiguration()
.BuildSessionFactory();
}
}
这可以创建一个有效的方案(我正在测试唱Sqlite并且可以看到正确创建的数据库)。问题是当我尝试保存实际实体时。
var p = new Product() { Name = "Product Sample", SKU = "12345", MSRP = 1.0 };
var sessionFactory = NHibernateUtils.CreateSessionFactory(...);
using (var session = sesionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
session.Save(p);
transaction.Commit();
}
}
此操作失败并显示错误“没有产品持久性”
好吧,我可以看到 - 所以接下来我尝试了这个session.Save((IProduct)p);
这给了我错误“没有IP产品的持久性”
那么我错过了什么?
注意:这是指向实际在正在运行的控制台应用中显示问题的要点的链接 https://gist.github.com/ravensorb/14193136002adbb3ec2fac07c026f921
答案 0 :(得分:3)
好像我已经成功了。尝试使用此重载object Save(string entityName, object obj);
。
这样的事情:
var p = new Product() { Name = "Product Sample" + i, SKU = "12345", MSRP = 1.0m };
session.Save(typeof(IProduct).FullName, p);
我调查了NHibernate持久性的源代码,发现持久性存储在Dictionary<string, IEntityPersister>
中,其中密钥来自Configuration.ClassMappings.EntityName
(在您的情况下为接口名称)。但是当你只调用Save(p)
时,你的entityName将等于你的实体类名,而不是接口。
我希望这清楚地解释:
产品没有持久性
答案 1 :(得分:0)
这是工作映射:
public class ProductMap : ClassMap<Product>
{
public ProductMap()
{
Id(x => x.Id).GeneratedBy.Guid();
Map(x => x.Name);
Map(x => x.SKU);
Map(x => x.MSRP);
}
}
public class OrderMap : ClassMap<Order>
{
public OrderMap()
{
Id(x => x.Id).GeneratedBy.Guid();
Map(x => x.CreatedOn);
HasMany<OrderLine>(x => x.Lines).Cascade.SaveUpdate();
}
}
public class OrderLineMap : ClassMap<OrderLine>
{
public OrderLineMap()
{
Id(x => x.Id).GeneratedBy.Guid();
Map(x => x.Qty);
Map(x => x.Price);
References<Product>(x => x.Product);
}
}
一些注意事项:
References
和HasMany
映射中明确指定具体类。小事:
.AddFromAssemblyOf<ProductMap>()
。.KeyColumns.Add(x => x.Id)
没有这样的重载(至少在最新的Fluent Nhibernate版本中)。transaction.Commit()
。看看非常相似的question。
以下是我测试保存的方法:
using (var transaction = session.BeginTransaction())
{
for (int i = 0; i < 10; i++)
{
Product p = new Product() { Name = "Product Sample" + i, SKU = "12345", MSRP = (1.0m + i) };
session.Save(p);
Order order = new Order
{
CreatedOn = DateTime.Now,
Lines = new List<IOrderLine> {
new OrderLine{ Price = 12, Qty = 2, Product = p}
}
};
session.Save(order);
}
transaction.Commit();
}