在nhibernate中搜索用户类型列

时间:2012-02-13 14:02:23

标签: nhibernate queryover

我有实体User,其中包含Status类型的属性DictionaryItem,并将其映射为UserType。现在我想制作以下linq语句:

Session.Query<User>().Where(x => x.LoginStatus.Code == "").ToList();

我遇到了以下异常:

  

其他信息:无法解析财产:代码:用户

我知道问题是我使用自定义类型进行搜索(属性代码存在于我的DictionaryItem用户类型中)。当我调用ToList()时,nhibernate会话查询会生成SQL语句,但LoginStatus不是引用类型,只有User类型,是否可以对用户类型进行查询?

编辑1: 源代码如下:

    public class User
{
    public virtual Guid Id { get; set; }
    public virtual DictionaryItem LoginStatus { get; set; }

    public User()
    {
    }
}

public class UserMap : ClassMap<User>
{
    public UserMap()
    {
        Id(x => x.Id);
        Map(x => x.LoginStatus).CustomType<DictionaryItemCustomType>();
    }
}
public class DictionaryItem
    {
        public virtual int Id { get; set; }
        public virtual string Code { get; set; }
        public virtual string Description { get; set; }
    }
 public class DictionaryItemCustomType : IUserType
    {
        public new bool Equals(object x, object y)
        {
            if (x == null && y == null)
            {
                return true;
            }
            if (x == null || y == null)
            {
                return false;
            }
            return ((DictionaryItem)x).Id == ((DictionaryItem)y).Id;
        }

        public int GetHashCode(object x)
        {
            return x.GetHashCode();
        }

        public object NullSafeGet(IDataReader rs, string[] names, object owner)
        {
            object value = NHibernateUtil.Int32.NullSafeGet(rs, names);
            if (value == null)
            {
                return null;
            }

            return AutofacServiceHostFactory.Container.Resolve<IDictionaryRepository>().DictionaryItems.First(x => x.Id == (int)value);
        }

        public void NullSafeSet(IDbCommand cmd, object value, int index)
        {
            DictionaryItem dictionaryItem = value as DictionaryItem;
            NHibernateUtil.Int32.NullSafeSet(cmd, dictionaryItem == null ? (object)null : dictionaryItem.Id, index);
        }

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

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

        public object Assemble(object cached, object owner)
        {
            throw new NotImplementedException();
        }

        public object Disassemble(object value)
        {
            throw new NotImplementedException();
        }

        public SqlType[] SqlTypes
        {
            get { return new[] { NHibernateUtil.Int32.SqlType }; }
        }

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

        public bool IsMutable
        {
            get { return false; }
        }
    }

Bd看起来像:

CREATE TABLE [dbo].[User](
    [Id] [uniqueidentifier] NOT NULL,   
    [LoginStatusId] [int] NOT NULL
)

CREATE TABLE [dbo].[DictionaryItem](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Code] [nvarchar](20) NOT NULL,
    [Description] [nvarchar](200) NOT NULL,
)

2 个答案:

答案 0 :(得分:1)

试试这个:

DictionaryItem statusAlias = null;
User userAlias = null;
return Session.QueryOver<User>(() => userAlias)
    .JoinAlias(() => userAlias.LoginStatus, () => statusAlias)
    .Where(() => statusAlias.Code == "")
    .ToList();

答案 1 :(得分:0)

您的映射不正确。不应将DictionaryItem映射为自定义类型。它看起来像我的另一个实体。

Map(x => x.LoginStatus).CustomType<DictionaryItemCustomType>();

以上表示您只想映射单个列。您想要将实际实体DictionaryItem映射到User。你需要做这样的事情:

References(x => x.LoginStatus, "LoginStatusId");

然后你需要映射DictionaryItem:

public class DictionaryItemMap : ClassMap<DictionaryItem>
{
    public DictionaryItemMap()
    {
        Id(x => x.Id);  //You'll need to do something else here for identity columns
        Map(x => x.Code);
        Map(x => x.Description);
    }
}

完成此映射后,您可以通过MGA进行上述查询。

LoginStatus statusAlias = null;
User userAlias = null;
return Session.QueryOver<User>(() => userAlias)
    .JoinAlias(() => userAlias.LoginStatus, () => statusAlias)
    .Where(() => statusAlias.Code == "")
    .ToList();