簡體   English   中英

如何從記錄的復合 ID 包含具有 null 值的鍵屬性的數據庫中加載實體?

[英]How do I load an entity from a database where the Composite ID of the record contains a key-property with a null value?

我正在使用 Oracle.DataAccess 通過 Oracle10g 提供程序從外部組織讀取數據。 其中一個表具有由這些字段組成的復合 ID。

course:
  institutioncode: "X11"
  coursecode:      "N100"
  campuscode:      "A"
  entryyear:       2011
  entrymonth:      10

問題是校園代碼被外部提供商允許為null,而不是為空。 這導致 nHibernate 返回包含 null 引用而不是課程實體的 collections。

其他域對象也將使用這些字段來引用此課程實體,因此這實際上用作鍵,我無法輕松地重新映射以使用代理鍵。

從標簽 3.1.0GA 的源代碼中,可以在Nhibernate.Type.ComponentType.Hydrate(IDataReader rs, string[] names, ISessionImplementor session, object owner)中找到導致此行為的檢查。 這總是拒絕密鑰屬性可能是 null 的可能性。 這種改變是否可以使可空性成為鍵屬性和鍵引用屬性的選項?

如果做不到這一點,你會如何推薦使用 nHibernate 直接讀取這些數據?

設計不支持屬性中的 NULL 值。

有兩種方法可以解決這個問題:

  • 導入數據而不是從源中使用原始數據,添加適當的代理鍵。
  • 在沒有 NHibernate 的情況下處理該實體。

好的,我的第一條評論沒有解決參考(ManyToOne)。 所以這里是我的替代解決方案:一個用戶類型來解決檢查。

class CourseMap : ClassMap<Course>
{
    public CourseMap()
    {
        CompositeId()
            .KeyProperty(c => c.InstitutionCode)
            .KeyProperty(c => c.CourseCode)
            .KeyProperty(c => c.CampusCode, key => key.Type(typeof(MyUserType)))
            .KeyProperty(c => c.EntryYear)
            .KeyProperty(c => c.EntryMonth);
    }
}

class MyUserType : IUserType
{
    public object Assemble(object cached, object owner)
    {
        return DeepCopy(cached);
    }

    public object DeepCopy(object value)
    {
        return value;
    }

    public object Disassemble(object value)
    {
        return DeepCopy(value);
    }

    public new bool Equals(object x, object y)
    {
        return object.Equals(x, y);
    }

    public int GetHashCode(object x)
    {
        return (x == null) ? 0 : x.GetHashCode();
    }

    public bool IsMutable
    {
        get { return false; }
    }

    public object NullSafeGet(IDataReader rs, string[] names, object owner)
    {
        var value = NHibernateUtil.String.NullSafeGet(rs, names[0]);
        return (value == null) ? string.Empty : value;
    }

    public void NullSafeSet(IDbCommand cmd, object value, int index)
    {
        string d = string.IsNullOrEmpty((string)value) ? null : (string)value;
        NHibernateUtil.String.NullSafeSet(cmd, d, index);
    }

    public object Replace(object original, object target, object owner)
    {
        return DeepCopy(original);
    }

    public Type ReturnedType
    {
        get { return typeof(string); }
    }

    public SqlType[] SqlTypes
    {
        get { return new[] { SqlTypeFactory.GetString(100) }; }
    }
}



class SomeEntityMap : ClassMap<SomeEntity>
{
    public EntityMap()
    {
        Id(e => e.Id).GeneratedBy.Assigned();

        References(e => e.Course)
            .Columns("InstitutionCode", "CourseCode", "CampusCode", "EntryYear", "EntryMonth")
            .Fetch.Join();  // important because we can't rely on values, NULL is invalid value
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM