【问题标题】:NHibernate - Unable to save child entitiesNHibernate - 无法保存子实体
【发布时间】:2015-02-17 08:42:49
【问题描述】:

这应该是一个简单的 1-N 关系,但是我无法保存孩子,因为 NHibernate 在孩子的插入语句中使用 null 作为值。

 public class Event
 {
  public virtual string Id { get; set; }
  public virtual string Name { get; set; }        
  public virtual IList<EventParameter> Parameters{ get; set; }

  public Event() { Parameters = new List<EventParameter>(); }
 }

[Serializable]
public class EventParameter : Parameter
{
  public virtual Event Event { get; set; }
  public virtual string ComparisonMethod { get; set; }
  public override bool Equals(object obj) {}
  public override int GetHashCode() {}
}

映射是这样的

public EventMapping()
{
    Table(...);

    Id(x => x.Id)
        .Column(...)
        .GeneratedBy
        .Custom<global::NHibernate.Id.SequenceGenerator>(builder => builder.AddParam("sequence", "...")); 

    Map(x => x.Name).Column("Name").Length(100);

    HasMany<EventParameter>(x => x.Parameters)
            .KeyColumns.Add(...)
            .Inverse()
            .Cascade.All();
}

public EventParameterMapping()
{
    Table(....);

    CompositeId()
        .KeyProperty(x => x.Event.Id, "...")
        .KeyProperty(x => x.ParameterId, "..."); 

    References(x => x.Event);          
}

父项的插入语句是正确的,但子项却不是。

INSERT INTO ...
        (...columns...)
VALUES  (..., null, ...)

在这种情况发生之前,我收到以下警告:无法确定实体是暂时的还是分离的;查询数据库。在会话中使用显式 Save() 或 Update() 来防止这种情况发生。

我确实在事务中使用了 Save()。任何想法为什么会发生这种情况?

【问题讨论】:

    标签: nhibernate fluent-nhibernate-mapping


    【解决方案1】:

    这里的解决方案非常简单。我们必须使用 inverse="true" 映射:

    HasMany<EventParameter>(x => x.Children)
            .KeyColumns.Add("...")
            .Inverse()
            .Cascade.All();
    

    但是,这是一种优化,需要在我们的 C# 代码中始终正确设置关系的双方:

    var parent = ...;
    var child = new Child();
    // both sides MUST be set
    parent.Children.Add(child);
    child.Parent = parent;
    

    请关注此以获取更多详细信息

    Inverse = “true” example and explanation

    【讨论】:

    • mmmm....我不在代码中做这种循环引用。我现在要试试这个。感谢您的建议。
    • 这个“循环引用”是 ORM 的核心。对象关系映射。我们映射关系。我发现许多争议都对此提出了挑战,但根据我的经验......如果您不想使用POCO (including relations) 表达业务领域模型......不要使用NHiberante(ORM)......但这是一个更大的话题。 ..只是...不要担心参考的东西。它是有效的 C# 和有效的 ORM ;)
    • 我删除了孩子的字符串 ID 属性并添加了一个父属性,现在我收到一个错误,它找不到“Id”属性的 getter。
    • 您应该使用代理键,为您的子元素合成。例如。 SQL Server 中自动生成的列。这应该映射到属性 ID。如果可能,不要复合键。其他任何事情(在受支持的情况下)都会导致许多问题。尝试按照文档中的标准方式(房地产):nhibernate.info/doc/nh/en/index.html#example-mappings。也许也请阅读:stackoverflow.com/a/28319725/1679310
    • 终于成功了,但一直很痛苦。非常感谢你的帮助。你有什么资源可以推荐吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多