Nibernate Fluent具有接口域模型和继承不保存 - 无法解析属性

时间:2018-02-18 16:13:39

标签: nhibernate fluent-nhibernate fluent-nhibernate-mapping

我上传了一个要点,其中包含一个工作示例,映射文件以及显示问题的完整调试日志 - https://gist.github.com/ravensorb/14193136002adbb3ec2fac07c026f921

以下是我得到的实际例外情况:

ERR: NHibernate.PropertyValueException: Error dehydrating property value for NHibernate.ConsoleTest.IOrderLine.Product ---> NHibernate.HibernateException: Unable to resolve property: Id
at NHibernate.Tuple.Entity.EntityMetamodel.GetPropertyIndex(String propertyName)
at NHibernate.Tuple.Entity.AbstractEntityTuplizer.GetPropertyValue(Object entity, String propertyPath)
at NHibernate.Persister.Entity.AbstractEntityPersister.GetPropertyValue(Object obj, String propertyName)
at NHibernate.Type.EntityType.GetReferenceValue(Object value, ISessionImplementor session)
at NHibernate.Type.ManyToOneType.NullSafeSet(DbCommand st, Object value, Int32 index, Boolean[] settable, ISessionImplementor session)
at NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id, Object[] fields, Object rowId, Boolean[] includeProperty, Boolean[][] includeColumns, Int32 table, DbCommand statement, ISessionImplementor session, Int32 index)

以下是演示此问题的代码的主要部分。在使用Id属性进行继承时,似乎可能存在问题?

class Program
{
    static void Main(string[] args)
    {
        try
        {
            var c = new Catalog { Name = "Catalog 1" };
            var p = new Product { Name = "Sample Product", SKU = "123456789", MSRP = (decimal)1.0, Catalog = c };
            var ol = new OrderLine { Product = p, Price = p.MSRP, Qty = 1 };
            var o = new Order { CreatedOn = DateTime.Now, Lines = new List<IOrderLine> { ol } };

            if (System.IO.File.Exists("test.db"))
            {
                System.IO.File.Delete("test.db");
            }

            var sessionFactory = NHibernateUtils.CreateSessionFactory(SQLiteConfiguration.Standard.UsingFile("test.db"));

            using (var session = sessionFactory.OpenSession())
            {
                using (var transaction = session.BeginTransaction())
                {
                    session.Save(typeof(IOrder).FullName, o);

                    transaction.Commit();
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception: {0}", ex);
            if (ex.InnerException != null) Console.WriteLine("InnerException: {0}", ex.InnerException);
        }

        Console.WriteLine("Press <ENTER> to exit....");
        Console.ReadLine();
    }
}

#region Interfaces

public interface IEntity
{
    Guid Id { get; set; }
}

public interface ICataglog : IEntity
{
    string Name { get; set; }
}

public interface IProduct : IEntity
{
    string Name { get; set; }
    string SKU { get; set; }
    decimal MSRP { get; set; }
    ICataglog Catalog { get; set; }
}

public interface IOrder : IEntity
{
    DateTime CreatedOn { get; set; }
    IList<IOrderLine> Lines { get; set; }
}

public interface IOrderLine : IEntity
{
    IProduct Product { get; set; }
    int Qty { get; set; }
    decimal Price { get; set; }
}
#endregion Interfaces

#region Class Maps

public class CatalogMap : ClassMap<ICataglog>
{
    public CatalogMap()
    {
        Table("tblCatalog");

        Id(x => x.Id)
            .Column("Id")
            .GeneratedBy.Assigned();

        Map(x => x.Name);
    }
}

public class ProductMap : ClassMap<IProduct>
{
    public ProductMap()
    {
        Table("tblProduct");

        Id(x => x.Id)
            .Column("Id")
            .GeneratedBy.Assigned();

        Map(x => x.Name);
        Map(x => x.SKU);
        Map(x => x.MSRP);

        References(x => x.Catalog)
            .Cascade.SaveUpdate();
    }
}

public class OrderMap : ClassMap<IOrder>
{
    public OrderMap()
    {
        Table("tblOrder");

        Id(x => x.Id)
            .Column("Id")
            .GeneratedBy.Assigned();

        Map(x => x.CreatedOn);

        HasMany(x => x.Lines)
            .Cascade.All()
            .KeyColumns.Add("Id");
    }
}

public class OrderLineMap : ClassMap<IOrderLine>
{
    public OrderLineMap()
    {
        Table("tbOrderLine");

        Id(x => x.Id)
            .Column("Id")
            .GeneratedBy.Assigned();

        Map(x => x.Qty);
        Map(x => x.Price);

        References(x => x.Product)
            .Cascade.SaveUpdate()
            .PropertyRef(x => x.Id)
            .ForeignKey("productId");
    }
}
#endregion Class Maps

public static class NHibernateUtils
{
    public static ISessionFactory CreateSessionFactory(IPersistenceConfigurer persistenceConfigurer)
    {
        return Fluently.Configure()
            .Database(persistenceConfigurer)
            .Mappings(m =>
            {
                m.FluentMappings.Add<CatalogMap>();
                m.FluentMappings.Add<ProductMap>();
                m.FluentMappings.Add<OrderMap>();
                m.FluentMappings.Add<OrderLineMap>();

                m.FluentMappings.ExportTo(System.Environment.CurrentDirectory);
            })
            .ExposeConfiguration(c => new SchemaExport(c).Create(false, true))
            .BuildConfiguration()
            .BuildSessionFactory();
    }
}

如果你想看到生成或想要重现问题的映射文件 - 请查看要点

1 个答案:

答案 0 :(得分:0)

我认为你使用了错误的id生成器。查看thisFluent NHibernate Generated AND Assigned ID Columns

分配意味着NHibernate将尝试插入已经初始化的标识符的实体(不是自己生成它) - target/jmeter/testFiles种类。

尝试使用它:

${__eval(${__FileToString(../testFiles/${data_file_name},,)})}

更新

如果您想使用SET IDENTITY_INSERT [dbo].[TableName] ON,请确保为所有实体明确指定了标识符:

Id(x => x.Id).GeneratedBy.Guid();

//Id(x => x.Id).GeneratedBy.Increment();//for numbers
//Id(x => x.Id).GeneratedBy.Identity();//for numbers

更新2:

我发现Id(x => x.Id).GeneratedBy.Assigned() var c = new Catalog { Name = "Catalog 1", Id = Guid.NewGuid() }; var p = new Product { Name = "Sample Product", SKU = "123456789", MSRP = (decimal)1.0, Catalog = c, Id = Guid.NewGuid() }; var ol = new OrderLine { Product = p, Price = p.MSRP, Qty = 1, Id = Guid.NewGuid() }; var o = new Order { CreatedOn = DateTime.Now, Lines = new List<IOrderLine> { ol }, Id = Guid.NewGuid() }; session.Save(typeof(ICatalog).FullName, c); session.Save(typeof(IProduct).FullName, p); session.Save(typeof(IOrderLine).FullName, ol); session.Save(typeof(IOrder).FullName, o); transaction.Commit(); 导致您的异常(不确定这是错误的)。尝试评论这些行,你不会有错误。