NHibernate - 错误脱水属性值 - 更新实体

Posted

技术标签:

【中文标题】NHibernate - 错误脱水属性值 - 更新实体【英文标题】:NHibernate - Error dehydrating property value - updating entity 【发布时间】:2019-02-15 04:38:39 【问题描述】:

我在保存具有关联的实体时遇到问题。下面是我的代码,它给出了错误

Fluent 类继承自 Fluent Migration

 public override void Up()  //Update your changes to the database
 
Create.Table("assinatura")
.WithColumn("id").AsInt32().Identity().PrimaryKey()
.WithColumn("usuario_id").AsInt32()
.WithColumn("isfreeplan").AsInt32()  //1 sim   0 nao
.WithColumn("gratuito_datafinal").AsDateTime()


Create.Table("usuarios")
.WithColumn("id").AsInt32().Identity().PrimaryKey()
.WithColumn("nomecompleto").AsString(256)     //Patricia dos Santos
.WithColumn("email").AsString(512)           //patricia@gmail.com
.WithColumn("password").AsString(128)        //123123123

Create.ForeignKey("IX_FK_AssinaturasUsuarios")
.FromTable("assinatura").ForeignColumn("usuario_id")
.ToTable("usuarios").PrimaryColumn("id");

“Usuario”表的映射

  public class UsuariosMap : ClassMapping<Usuario>
    


  public enum Niveis  CADASTRADO = 0, REQUISITOU_PAGAMENTO = 1 
        public virtual int id  get; set; 
        public virtual string nomecompleto  get; set; 
        public virtual string email  get; set; 
        public virtual string password  get; set; 

        public UsuariosMap()
        
            Table("usuarios");
            Id(x => x.id, x => x.Generator(Generators.Identity));
            Property(x => x.nomecompleto, x => x.NotNullable(true));
            Property(x => x.email, x => x.NotNullable(true));
            Property(x => x.password, x => x.NotNullable(true));
            Bag(x => x.assinaturas, map => 
                map.Table("assinatura");
                map.Lazy(CollectionLazy.Lazy);
                map.Inverse(true);
                map.Key(k => k.Column(col => col.Name("usuario_id")));
                map.Cascade(Cascade.All); //set cascade strategy
            , rel => rel.OneToMany());

        

“Assinatura”表的映射

 public class Assinatura
    
        public virtual int Id  get; set; 

        public virtual int usuario_id  get; set; 

        public virtual int isfreeplan  get; set; 
        public virtual DateTime gratuito_datafinal  get; set; 
        public virtual Usuario usuario  get; set; 

    
   public class AssinaturaMap : ClassMapping<Assinatura>
    
        public AssinaturaMap()
        
            Table("assinatura");
            Id(x => x.Id, x => x.Generator(Generators.Identity));
            Property(x => x.usuario_id, x => x.NotNullable(true));
            Property(x => x.isfreeplan, x => x.NotNullable(true));
            Property(x => x.gratuito_datafinal, x => x.NotNullable(true));

            ManyToOne(x => x.usuario, x=>
            
                x.Cascade(Cascade.DeleteOrphans);
                x.Column("usuario_id");
                x.ForeignKey("IX_FK_AssinaturasUsuarios");
            );
        
    

当我尝试更新用户“Usuario”并添加新的“Assinatura”时出现错误

 var user = Database.Session.Load<Usuario>(1);
            var ass = new Assinatura
            
                isfreeplan = 0,
                gratuito_datafinal = DateTime.Now,
                usuario = user
            ;

            if (user != null)
            
                user.assinaturas.Add(ass);
                Database.Session.SaveOrUpdate(user);
            

“NHibernate.PropertyValueException”类型的异常发生在 NHibernate.dll 中,但未在用户代码中处理 “Test.Models.Assinatura.usuario 脱水属性值出错” Inner Exc: "参数索引超出范围。" 属性名称:usuario

我只想在 Usuario 表和 Assinature 表之间建立基本的一对多关系(1 个用户有一个或多个 assinaturas)。

【问题讨论】:

【参考方案1】:

例外:

参数索引超出范围

告诉我们,我们正在使用一个 DB 列两次。那是因为这种双重映射:

    Property(x => x.usuario_id, x => x.NotNullable(true));

    ManyToOne(x => x.usuario, x=>
    
        x.Cascade(Cascade.DeleteOrphans);
        x.Column("usuario_id");
        ...

可以将一列用于更多属性(一种值类型,一种引用).. 但仅用于读取(从数据库加载值)

对于插入/更新...我们只能使用其中之一。并且总是更好地保持读/写引用和只读属性

    Property(x => x.usuario_id, x => 
        x.NotNullable(true)
        x.Insert(false)
        x.Update(false)
    )

【讨论】:

以上是关于NHibernate - 错误脱水属性值 - 更新实体的主要内容,如果未能解决你的问题,请参考以下文章

NHibernate:错误脱水属性 - 这到底是什么?

插入时 NHibernate 组件非空属性

将引用作为属性的 Nhibernate 映射值对象

这个错误在 nhibernate 中是啥意思

当设置了级联保存更新属性时,NHibernate 会不必要地更新对象吗?

NHibernate - 仅更新在运行时识别的指定对象属性