メモリフィルターのSubSonic .Filter()
質問
subsonicで.Filter()メソッドを使用する際に問題が発生し、以下のようなエラーが常に発生しています:
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
Line 36: bool remove = false;
Line 37: System.Reflection.PropertyInfo pi = o.GetType().GetProperty(w.ColumnName);
Line 38: if (pi.CanRead)
Line 39: {
Line 40: object val = pi.GetValue(o, null);
私は以下のような呼び出しを行っています-これはそれを使用する現在の方法ですか?このメソッドの使用に関するドキュメントはないようです
NavCollection objTopLevelCol = objNavigation.Where(Nav.Columns.NavHigherID,Comparison.Equals, 0).Filter();
事前に感謝
解決
フィルタリングする値は、データベース列名ではなくプロパティ名である必要があります。
これを試すことができます:
lCol = objNavigation.Where(Nav.HigherIDColumn.PropertyName,Comparison.Equals, 0).Filter();
またはここに、.Filter()メソッドのカスタムオーバーライドに基づいて機能する、もう少し冗長なメソッドがあります。 Whereを事前に明示的に作成することにより、(少なくとも私にとっては)うまくいくように見えました:
SubSonic.Where w = new SubSonic.Where();
w.ColumnName = Nav.HigherIDColumn.PropertyName;
w.Comparison = SubSonic.Comparison.NotIn;
w.ParameterValue = new string[] { "validvalue1", "validvalue2" };
lCol = objNavigation.Filter(w, false);
オーバーライドは次のとおりです。
/// <summary>
/// Filters an existing collection based on the set criteria. This is an in-memory filter.
/// All existing wheres are retained.
/// </summary>
/// <returns>NavCollection</returns>
public NavCollection Filter(SubSonic.Where w)
{
return Filter(w, false);
}
/// <summary>
/// Filters an existing collection based on the set criteria. This is an in-memory filter.
/// Existing wheres can be cleared if not needed.
/// </summary>
/// <returns>NavCollection</returns>
public NavCollection Filter(SubSonic.Where w, bool clearWheres)
{
if (clearWheres)
{
this.wheres.Clear();
}
this.wheres.Add(w);
return Filter();
}
/// <summary>
/// Filters an existing collection based on the set criteria. This is an in-memory filter.
/// Thanks to developingchris for this!
/// </summary>
/// <returns>NavCollection</returns>
public NavCollection Filter()
{
for (int i = this.Count - 1; i > -1; i--)
{
Nav o = this[i];
foreach (SubSonic.Where w in this.wheres)
{
bool remove = false;
System.Reflection.PropertyInfo pi = o.GetType().GetProperty(w.ColumnName);
if (pi != null && pi.CanRead)
{
object val = pi.GetValue(o, null);
if (w.ParameterValue is Array)
{
Array paramValues = (Array)w.ParameterValue;
foreach (object arrayVal in paramValues)
{
remove = !Utility.IsMatch(w.Comparison, val, arrayVal);
if (remove)
break;
}
}
else
{
remove = !Utility.IsMatch(w.Comparison, val, w.ParameterValue);
}
}
if (remove)
{
this.Remove(o);
break;
}
}
}
return this;
}
そして、SubSonic 2.0はIsMatch関数のIn / NotInを実際にサポートしていないため、カスタマイズしたバージョンは次のとおりです(SubSonic \ Utility.csで):
public static bool IsMatch(SubSonic.Comparison compare, object objA, object objB)
{
if (objA.GetType() != objB.GetType())
return false;
bool isIntegerVal = (typeof(int) == objA.GetType());
bool isDateTimeVal = (typeof(DateTime) == objA.GetType());
switch (compare)
{
case SubSonic.Comparison.In:
case SubSonic.Comparison.Equals:
if (objA.GetType() == typeof(string))
return IsMatch((string)objA, (string)objB);
else
return objA.Equals(objB);
case SubSonic.Comparison.NotIn:
case SubSonic.Comparison.NotEquals:
return !objA.Equals(objB);
case SubSonic.Comparison.Like:
return objA.ToString().Contains(objB.ToString());
case SubSonic.Comparison.NotLike:
return !objA.ToString().Contains(objB.ToString());
case SubSonic.Comparison.GreaterThan:
if (isIntegerVal)
{
return ((int)objA > (int)objB);
}
else if (isDateTimeVal)
{
return ((DateTime)objA > (DateTime)objB);
}
break;
case SubSonic.Comparison.GreaterOrEquals:
if (isIntegerVal)
{
return ((int)objA >= (int)objB);
}
else if (isDateTimeVal)
{
return ((DateTime)objA >= (DateTime)objB);
}
break;
case SubSonic.Comparison.LessThan:
if (isIntegerVal)
{
return ((int)objA < (int)objB);
}
else if (isDateTimeVal)
{
return ((DateTime)objA < (DateTime)objB);
}
break;
case SubSonic.Comparison.LessOrEquals:
if (isIntegerVal)
{
return ((int)objA <= (int)objB);
}
else if (isDateTimeVal)
{
return ((DateTime)objA <= (DateTime)objB);
}
break;
}
return false;
}
他のヒント
.net 3.5を使用している場合、ラムダ関数を使用してこれを行うことができます。
NavCollection objTopLevelCol =
objNavigation.Where(nav => nav.NavHigherID == 0);
フィルタは、コレクションで動作するように設計されています-「objNavigation」コレクション?実行中の問題は、Filter()の基準が列名「NavHigherID」で満たせないことです。
同じ問題が発生していました。次のようにフィルターを実行してみてください:
lCol = objNavigation.Where("NavHigherID",Comparison.Equals, 0).Filter();
所属していません StackOverflow