Привет. По моим знаниям позвольте мне прояснить концепцию конструктора по умолчанию:
Компилятор автоматически предоставляет конструктор по умолчанию, не содержащий аргументов, для любого класса без конструкторов. Этот конструктор по умолчанию вызовет конструктор без аргументов суперкласса. В этой ситуации компилятор будет жаловаться, если суперкласс не имеет конструктора без аргументов, поэтому вы должны убедиться, что он это делает. Если у вашего класса нет явного суперкласса, то он имеет неявный суперкласс Object, у которого нет конструктора без аргументов.
blockquote>Я прочитал эту информацию из учебных пособий Java .
Первое, что нужно сделать состоит в том, чтобы поставить вход, для наблюдения, какой TSQL был сгенерирован; например:
ctx.Log = Console.Out;
LINQ к SQL, кажется, рассматривает, аннулирует немного несовместимо (в зависимости от литерала по сравнению со значением):
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
:
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);
}
Что относительно чего-то более простого как это?
public IEnumerable<ICategory> GetSubCategories(long? categoryId)
{
var subCategories = this.Repository.Categories.Where(c => (!categoryId.HasValue && c.ParentId == null) || c.ParentId == categoryId)
.ToList().Cast<ICategory>();
return subCategories;
}
Мое предположение - то, что это происходит из-за довольно общего атрибута DBMS - Просто, потому что две вещи являются оба пустыми, не означает, что они равны.
Для разработки немного попытайтесь выполнить эти два запроса:
SELECT * FROM TABLE WHERE field = NULL
SELECT * FROM TABLE WHERE field IS NULL
причиной "ЯВЛЯЕТСЯ ПУСТАЯ" конструкция, то, что в мире DBMS, ПУСТОМ УКАЗАТЕЛЕ! = ПУСТОЙ УКАЗАТЕЛЬ начиная со значения ПУСТОГО УКАЗАТЕЛЯ - то, что значение не определено. Начиная с ПУСТЫХ неопределенных средств Вы не можете сказать, что два нулевых значения равны, так как по определению Вы не знаете, каковы они.
, Когда Вы явно проверяете на "поле == ПУСТОЙ УКАЗАТЕЛЬ", LINQ, вероятно, преобразовывает это в "поле IS NULL". Но когда Вы используете переменную, я предполагаю, что LINQ автоматически не делает того преобразования.
Вот сообщение форума MSDN с большим количеством информации об этой проблеме.
Похож на хороший "обман", должен изменить Вашу лямбду для сходства с этим:
c => c.ParentId.Equals(categoryId)