我有以下情形:在NHibernate中查詢用戶類型
假設我在此舊數據庫中的「產品」表具有字符串類型的「類別」列。此列存儲類別ID由某種ascii字符分隔。例如:「| 1 |」 (對於類別1),「| 1 | 2 | 3 |」 (對於類別1,2,3)等
而不是公開一個字符串屬性,我想公開一個IEnumerable,以便我的產品類的用戶不必擔心解析這些值。
我創建一個SelectedCatories類型簡直是一個IEnumerable,我的產品類看起來是這樣的:
public class Product
{
public virtual Guid Id { get; set; }
public virtual string Name { get; set; }
public virtual bool Discontinued { get; set; }
public virtual SelectedCategories Categories { get; set; }
}
然後,我創建了一個SelectedCategoriesUserType類,像這樣:
public class SeletedCategoriesUserType : IUserType
{
static readonly SqlType[] _sqlTypes = {NHibernateUtil.String.SqlType};
public bool Equals(object x, object y)
{
// Fix this to check for Categories...
if (ReferenceEquals(x, y)) return true;
if (x == null || y == null) return false;
return x.Equals(y);
}
public int GetHashCode(object x)
{
return x.GetHashCode();
}
public object NullSafeGet(IDataReader rs, string[] names, object owner)
{
object obj = NHibernateUtil.String.NullSafeGet(rs, names[0]);
if (obj == null) return null;
string[] stringCategories = obj.ToString().Split(new[] {'|'}, StringSplitOptions.RemoveEmptyEntries);
var categories = new Categories();
return
new SelectedCategories(
stringCategories.Select(
stringCategory => categories.Single(cat => cat.Id == int.Parse(stringCategory)))
.ToList());
}
public void NullSafeSet(IDbCommand cmd, object value, int index)
{
if (value == null)
{
((IDataParameter) cmd.Parameters[index]).Value = DBNull.Value;
}
else
{
var theCategories = (SelectedCategories) value;
var builder = new StringBuilder();
builder.Append("|");
theCategories.ForEach(i => builder.AppendFormat("{0}|", i.Id.ToString()));
((IDataParameter) cmd.Parameters[index]).Value = builder.ToString();
}
}
public object DeepCopy(object value)
{
return value;
}
public object Replace(object original, object target, object owner)
{
throw new NotImplementedException();
}
public object Assemble(object cached, object owner)
{
throw new NotImplementedException();
}
public object Disassemble(object value)
{
throw new NotImplementedException();
}
public SqlType[] SqlTypes
{
get { return _sqlTypes; }
}
public Type ReturnedType
{
get { return typeof (SelectedCategories); }
}
public bool IsMutable
{
get { return false; }
}
}
我當時想建立一個查詢,讓我回到屬於特定類別(比如2類)的任何產品,匹配「| 2 |」和「| 1 | 2 | 3 |」。
現在,我天真的實現,勉強讓我測試通過如下:
public IEnumerable<Product> GetByCategory(Category category)
{
using (ISession session = NHibernateHelper.OpenSession())
{
return session
.CreateSQLQuery("select * from product where categories LIKE :category")
.AddEntity(typeof(Product))
.SetString("category", string.Format("%|{0}|%", category.Id))
.List()
.Cast<Product>();
}
}
我的問題是:什麼是要正確的查詢的正確方法?
只是爲了闡明:該查詢不適合您,或者您想知道一種「更乾淨」的方式來編寫您的查詢嗎?而且它是強制性的,你的類別ID由|分隔或者他們也可以用逗號(,)分隔? – Max 2010-11-15 21:03:00