界面的 XML 注释ICompositeUserType
告诉我:
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 子句的情况下执行可以正常工作。