我有一个Category实体,该实体具有Nullable ParentId字段。当下面的方法正在执行且categoryId为null时,结果似乎为null,但是有些类别的ParentId值为null。
这里有什么问题,我想念什么?
public IEnumerable<ICategory> GetSubCategories(long? categoryId) { var subCategories = this.Repository.Categories.Where(c => c.ParentId == categoryId) .ToList().Cast<ICategory>(); return subCategories; }
顺便说一句,当我将条件更改为(c.ParentId == null)时,结果似乎正常。
首先要做的是进行日志记录,以查看生成了什么TSQL。例如:
ctx.Log = Console.Out;
LINQ-to-SQL似乎对null的处理有些不一致(取决于文字与值):
using(var ctx = new DataClasses2DataContext()) { ctx.Log = Console.Out; int? mgr = (int?)null; // redundant int? for comparison... // 23 rows: var bosses1 = ctx.Employees.Where(x => x.ReportsTo == (int?)null).ToList(); // 0 rows: var bosses2 = ctx.Employees.Where(x => x.ReportsTo == mgr).ToList(); }
因此,我只能建议使用带空值的顶级表格!
即
Expression<Func<Category,bool>> predicate; if(categoryId == null) { predicate = c=>c.ParentId == null; } else { predicate = c=>c.ParentId == categoryId; } var subCategories = this.Repository.Categories .Where(predicate).ToList().Cast<ICategory>();
更新-我使用自定义功能使其“正常”工作Expression:
Expression
static void Main() { ShowEmps(29); // 4 rows ShowEmps(null); // 23 rows } static void ShowEmps(int? manager) { using (var ctx = new DataClasses2DataContext()) { ctx.Log = Console.Out; var emps = ctx.Employees.Where(x => x.ReportsTo, manager).ToList(); Console.WriteLine(emps.Count); } } static IQueryable<T> Where<T, TValue>( this IQueryable<T> source, Expression<Func<T, TValue?>> selector, TValue? value) where TValue : struct { var param = Expression.Parameter(typeof (T), "x"); var member = Expression.Invoke(selector, param); var body = Expression.Equal( member, Expression.Constant(value, typeof (TValue?))); var lambda = Expression.Lambda<Func<T,bool>>(body, param); return source.Where(lambda); }