LINQ NullReferenceException для простого выбора - PullRequest
1 голос
/ 30 ноября 2011

Следующий код генерирует исключение NullReferenceException.Если я фильтрую пользовательскую таблицу, используя другой столбец, исключение не выдается.Столбцы типа DateTime вызывают это исключение.

using (MyDataContext dc = new MyDataContext())
    {
        var ids = dc.Users.Where(c => c.BirthDate < DateTime.Now.AddYears(-10)).Select(c => c.UserId);

        var list = (from c in dc.Users
                    where ids.Contains(c.UserId)
                    select c).ToList();
    }

Трассировка стека так:

[NullReferenceException: Object reference not set to an instance of an object.]


System.Data.Linq.SqlClient.SqlFactory.Member(SqlExpression expr, MemberInfo member) +182
   System.Data.Linq.SqlClient.QueryConverter.VisitMemberAccess(MemberExpression ma) +260
   System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node) +939
   System.Data.Linq.SqlClient.QueryConverter.Visit(Expression node) +18
   System.Data.Linq.SqlClient.QueryConverter.VisitExpression(Expression exp) +18
   System.Data.Linq.SqlClient.QueryConverter.VisitMethodCall(MethodCallExpression mc) +1011
   System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node) +1003
   System.Data.Linq.SqlClient.QueryConverter.Visit(Expression node) +18
   System.Data.Linq.SqlClient.QueryConverter.VisitExpression(Expression exp) +18
   System.Data.Linq.SqlClient.QueryConverter.VisitChangeType(Expression expression, Type type) +12
   System.Data.Linq.SqlClient.QueryConverter.VisitCast(UnaryExpression c) +117
   System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node) +619
   System.Data.Linq.SqlClient.QueryConverter.Visit(Expression node) +18
   System.Data.Linq.SqlClient.QueryConverter.VisitExpression(Expression exp) +18
   System.Data.Linq.SqlClient.QueryConverter.VisitBinary(BinaryExpression b) +35
   System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node) +427
   System.Data.Linq.SqlClient.QueryConverter.Visit(Expression node) +18
   System.Data.Linq.SqlClient.QueryConverter.VisitExpression(Expression exp) +18
   System.Data.Linq.SqlClient.QueryConverter.VisitBinary(BinaryExpression b) +35
   System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node) +427
   System.Data.Linq.SqlClient.QueryConverter.Visit(Expression node) +18
   System.Data.Linq.SqlClient.QueryConverter.VisitExpression(Expression exp) +18
   System.Data.Linq.SqlClient.QueryConverter.VisitWhere(Expression sequence, LambdaExpression predicate) +125
   System.Data.Linq.SqlClient.QueryConverter.VisitSequenceOperatorCall(MethodCallExpression mc) +3403
   System.Data.Linq.SqlClient.QueryConverter.VisitMethodCall(MethodCallExpression mc) +74
   System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node) +1003
   System.Data.Linq.SqlClient.QueryConverter.Visit(Expression node) +18
   System.Data.Linq.SqlClient.QueryConverter.VisitSelect(Expression sequence, LambdaExpression selector) +17
   System.Data.Linq.SqlClient.QueryConverter.VisitSequenceOperatorCall(MethodCallExpression mc) +1368
   System.Data.Linq.SqlClient.QueryConverter.VisitMethodCall(MethodCallExpression mc) +74
   System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node) +1003
   System.Data.Linq.SqlClient.QueryConverter.Visit(Expression node) +18
   System.Data.Linq.SqlClient.QueryConverter.VisitContains(Expression sequence, Expression value) +377
   System.Data.Linq.SqlClient.QueryConverter.VisitSequenceOperatorCall(MethodCallExpression mc) +9129
   System.Data.Linq.SqlClient.QueryConverter.VisitMethodCall(MethodCallExpression mc) +74
   System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node) +1003
   System.Data.Linq.SqlClient.QueryConverter.Visit(Expression node) +18
   System.Data.Linq.SqlClient.QueryConverter.VisitExpression(Expression exp) +18
   System.Data.Linq.SqlClient.QueryConverter.VisitWhere(Expression sequence, LambdaExpression predicate) +125
   System.Data.Linq.SqlClient.QueryConverter.VisitSequenceOperatorCall(MethodCallExpression mc) +3403
   System.Data.Linq.SqlClient.QueryConverter.VisitMethodCall(MethodCallExpression mc) +74
   System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node) +1003
   System.Data.Linq.SqlClient.QueryConverter.ConvertOuter(Expression node) +79
   System.Data.Linq.SqlClient.SqlProvider.BuildQuery(Expression query, SqlNodeAnnotations annotations) +114
   System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query) +132
   System.Data.Linq.DataQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() +35
   System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +7667686
   System.Linq.Enumerable.ToList(IEnumerable`1 source) +61
   lab_test.Page_Load(Object sender, EventArgs ee) in d:\Projeler\Kardelen\Kod\Kardelen.Web.UI\lab\test.aspx.cs:543
   System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14
   System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35
   System.Web.UI.Control.OnLoad(EventArgs e) +99
   System.Web.UI.Control.LoadRecursive() +50
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +627

Кто-нибудь получает это исключение?

Спасибо за ответ.

Ответы [ 2 ]

5 голосов
/ 30 ноября 2011

Если я фильтрую пользовательскую таблицу, используя другой столбец, исключение не выдается. Столбцы типа DateTime вызывают это исключение.

Предполагая, что вы имеете в виду это сравнение: c.BirthDate < DateTime.Now.AddYears(-10)

Скорее всего BirthDate равно null. Если в вашем сценарии достаточно просто пропустить этих пользователей, вы можете добавить проверку, чтобы проверить, является ли она нулевой, перед выполнением сравнения дат.

В качестве идентификатора вы, вероятно, должны определить DateTime.Now.AddYears(-10) один раз перед вызовом Where, чтобы предотвратить его пересчет, и, что еще хуже, из-за изменения значения во времени.

DateTime tenYearsAgo = DateTime.Now.AddYears(-10);
var ids = dc.Users
    .Where(c => c.BirthDate != null && c.BirthDate < tenYearsAgo)
    .Select(c => c.UserId);
1 голос
/ 30 ноября 2011

Скорее всего, c.BirthDate свойство обнуляется , DateTime? BirthDate.

Это будет соответствовать столбцу Allow-NULL в вашей таблице.

Достаточно простой проверки:

 dc.Users.Where(c => c.BirthDate.HasValue 
       && (c.BirthDate < DateTime.Now.AddYears(-10))
 )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...