c# - Nhibernate - 将通用 IList 对象映射到单个 DB 列中以逗号分隔的键列表

标签 c# nhibernate

我在这里可能过于雄心勃勃,但我希望有人能够提出解决方案。

我有许多 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/

相关文章:

c# - NuGet.targets“无法再次导入。已导入警告

c# - 从泛型方法问题调用重载方法

c# - 哪种 .NET 数据类型最适合在 NHibernate 中映射 NUMBER Oracle 数据类型?

nhibernate - 寻找有关嵌入式.NET数据库(例如db4o,NHibernate或RavenDB)的指南

asp.net-mvc-3 - Mono 上的 NHibernate 运行 ASP.NET MVC 3 Web 应用程序

c# - File.Exists 方法是否获得大量资源?

c# - 如何让 ASP.NET MVC 应用程序使用我的成员资格表?

c# - 确保服务连通性

nhibernate - 在 NHibernate 中,如何找到知道其类型的持久性 POCO 类的 id 属性的名称?

nhibernate - 找不到 SchemaExport 的重载执行方法