1

ICompositeUserTypeインターフェイスの XML コメントは次のことを示しています。

This interface allows a custom type to define "properties".
--> These need not necessarily correspond to physical .NET style properties.

複数の列をリストにマップするような場合があります。

// Each column is mapped into this object
public class IdentifiedValue
{
    public string Name;
    public object Value;
}

public class CompanyContainer
{
    public virtual int Id { get; set; }
    public virtual IList<IdentifiedValue> Values { get; set; }
}

// The columns being mapped:
public class GeneratedColumns
{
    public static string[] ColumnsInfo
    {
        get
        {
            return new[]
                {
                    "CODE_TYPE",
                    "CODE_VALUE",
                    "CODE_DESC_NL",
                    "CODE_DESC_FR",
                    "CODE_DESC_EN"
                };
        }
    }
}

ICompositeUserType の実装: (無関係なメソッドは省略)

public class IdentifiedValueMapper : ICompositeUserType
{
    public string[] PropertyNames
    {
        get
        {
            var result = new List<string>();
            foreach (var columnInfo in GeneratedColumns.ColumnsInfo)
            {
                result.Add(columnInfo);
            }
            return result.ToArray();
        }
    }

    public object NullSafeGet(IDataReader dr, string[] names, ISessionImplementor session, object owner)
    {
        if (dr == null)
        {
            return null;
        }
        var result = new List<IdentifiedValue>();
        for (int i = 0; i < names.Length; i++)
        {
            var value = NHibernateUtil.String.NullSafeGet(dr, names[i], session, owner) as string;
            result.Add(new IdentifiedValue()
                {
                    Name = names[i],
                    Value = value
                });
        }
        return result;
    }

    public IType[] PropertyTypes
    {
        get
        {
            var result = new List<IType>();
            foreach (var columnInfo in GeneratedColumns.ColumnsInfo)
            {
                result.Add(NHibernateUtil.String);
            }
            return result.ToArray();
        }
    }

    public Type ReturnedClass
    {
        get { return typeof(List<IdentifiedValue>); }
    }
}

マッピング自体

public class CompanyContainerMap : ClassMap<CompanyContainer>
{
    public CompanyContainerMap()
    {
        Table("S1073_CODE");
        Id(x => x.Id).Column("CODE_ID");
        var cols = Map(x => x.Values)
            .CustomType<IdentifiedValueMapper>()
            .Columns.Clear();

        foreach (var col in GeneratedColumns.ColumnsInfo)
        {
            cols.Columns.Add(col);
        }
    }
}

失敗したテスト コード:

    [TestMethod]
    public void TestMethod1()
    {
        var factory = BuildSessionFactory();

        using (var session = factory.OpenSession())
        {
            var query = session.QueryOver<CompanyContainer>();
            query.Where(Restrictions.Eq("CODE_VALUE", "1"));
            var result = query.List();
            var blah = result;
        }
    }

クエリ実行時の例外: could not resolve property: CODE_VALUE of: CompanyContainer

そのため、まだ存在しない CompanyContainer.CODE_VALUE にアクセスしようとしているようです。生成したいだけなので、なぜ.NETプロパティにアクセスしたいのかわかりませんWHERE CODE_VALUE='1'

Where 句なしで実行すると、正しく機能します。

4

1 に答える 1