我在这里可能过于雄心勃勃,但我希望有人能够提出解决方案。
我有许多 UserChoice 对象,例如 TravellingChoices、SocialisingChoices、SportChoices 等,在用户配置文件中,每个用户都准确指定他们属于哪一个,因此在数据库中,他们有一个配置文件行与对应的 INT id 映射到他们选择的选择选项的键。
当您使用 NHibernate 加载配置文件时,我使用多对一映射来构建一个配置文件对象,该对象实际上包含 TravellingChoice、SocialisingChoice、SportChoice 等对象本身,而不是我想要的 ID。
问题是我希望人们能够搜索符合特定条件的其他用户,但您可以选择多个用户。例如,具有两种不同旅行选择之一的用户,或者您可以选择 3 种运动选择进行搜索。
所以我想将搜索条件对象作为许多强类型列表保存在内存中,例如
IList<TravellingChoice>
IList<SocialisingChoice>
等等。
问题是我将搜索条件对象存储在 db 中,作为许多列,这些列具有 id 分隔列表 例如
SocialisingChoicesColumn : 1,2,6
TravellingChoicesColumn : 5,8
等..
我希望能够做的是让 nhibernate 映射获取我的表,如果 id/comma 列表,则列已满,并将每个列转换为具有完全填充对象的相关 Typed Ilist。
那么我如何从带有 id/comma 列表的上表转到带有
的对象IList<TravellingChoice>
IList<SocialisingChoice>
等等 属性?
这对于 Nhibernate 来说可能还是太复杂了?
最佳答案
是的,ICompositeUserType
。你可以在此基础上构建
class MyUserType<TChoice> : ICompositeUserType
{
public object Assemble(object cached, ISessionImplementor session, object owner)
{
return DeepCopy(cached);
}
public object DeepCopy(object value)
{
return ((IList<TChoice>)value).ToList();
}
public object Disassemble(object value, ISessionImplementor session)
{
return DeepCopy(value);
}
bool ICompositeUserType.Equals(object x, object y)
{
var list1 = x as IList<TChoice>;
var list2 = y as IList<TChoice>;
return (x == null) ? y == null : list1.SequenceEqual(list2);
}
public int GetHashCode(object x)
{
// example implementation
var list = x as IList<TChoice>;
unchecked
{
return list == null ? 0 : list.Sum(choice => choice.GetHashCode());
}
}
public object GetPropertyValue(object component, int property)
{
// the list has no properties to get
throw new NotSupportedException();
}
public bool IsMutable
{
get { return true; }
}
public object NullSafeGet(IDataReader dr, string[] names, ISessionImplementor session, object owner)
{
var str = (string)NHibernateUtil.String.Get(dr, names[0]);
IList<int> ids = str.Split(',').Select(id => int.Parse(id.Trim())).ToList();
// HACK: assuming session also implements ISession
return ((ISession)session).QueryOver<TChoice>()
.WhereRestrictionOn(choice => choice.Id).IsInG(ids)
.List();
}
public void NullSafeSet(IDbCommand cmd, object value, int index, bool[] settable, NHibernate.Engine.ISessionImplementor session)
{
var list = value as IList<TChoice>;
NHibernateUtil.String.Set(cmd, string.Join(", ", list.Select(choice => choice.Id.ToString()).ToArray()), index);
}
public string[] PropertyNames
{
get { return new string[0]; }
}
public IType[] PropertyTypes
{
get { return new IType[0]; }
}
public object Replace(object original, object target, NHibernate.Engine.ISessionImplementor session, object owner)
{
return original;
}
public Type ReturnedClass
{
get { return typeof(IList<TChoice>); }
}
public void SetPropertyValue(object component, int property, object value)
{
// the list has no properties to set
throw new NotSupportedException();
}
}
关于c# - Nhibernate - 将通用 IList 对象映射到单个 DB 列中以逗号分隔的键列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9633040/