igor-tkachev / bltoolkit

Business Logic Toolkit for .NET
MIT License
297 stars 112 forks source link

Outer Apply FirstOrDefault throws Object reference not set to an instance of an object. #347

Closed croban closed 8 years ago

croban commented 9 years ago

var query = from newItem in dbArchive.AsQueryable() select new { Item=newItem, PreviousItem=(from z in dbArchive.AsQueryable() join tmp in ( from y in dbArchive.AsQueryable() where y.LogId < newItemc.LogId && y.Id == newItem.Id group y by y.Id into g select new { LogId = g.Max(f => f.LogId) } ) on z.LogId equals tmp.LogId select z).FirstOrDefault() }

Creates correct sql query with outer apply just the items which does not have previous items throws "Object reference not set to an instance of an object" on materialization of object.

ili commented 9 years ago

Can you provide stack trace, plz.

croban commented 9 years ago

Hi, here is stack trace

at XXX.BusinessLogic.DAL.Model.Archive.ArchiveCustomerCampaign$TypeAccessor.Accessor$LeadState.SetValue(Object o, Object value) at BLToolkit.Mapping.DefaultMemberMapper.SetValue(Object o, Object value) at BLToolkit.Mapping.ObjectMapper.SetValue(Object o, Int32 index, Object value) at BLToolkit.Mapping.ValueMapping.DefaultValueMapper.Map(IMapDataSource source, Object sourceObject, Int32 sourceIndex, IMapDataDestination dest, Object destObject, Int32 destIndex) at BLToolkit.Data.Linq.Builder.TableBuilder.TableContext.MapDataReaderToObject1(IDataReader dataReader, MappingData data) at lambda_method(Closure , QueryContext , IDataContext , IDataReader , Expression , Object[] ) at BLToolkit.Data.Linq.Query1.<Map>d__60.MoveNext() at LINQPad.ObjectGraph.ListNode.<GetItems>d__8.MoveNext() at System.Collections.Generic.List1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source) at LINQPad.ObjectGraph.ListNode..ctor(ObjectNode parent, IEnumerable list, GraphOptions options, String name) at LINQPad.ObjectGraph.ObjectNode.CreateInternal(ObjectNode parent, Object item, GraphOptions options)

ili commented 9 years ago

I need to see your class definition, but it looks like that ArchiveCustomerCampaign.LeadState does not accept nullable values, but we do have null in dataset...

another moment, try to:

var query = from newItem in dbArchive.AsQueryable() 
 select new {
 Item=newItem,
 PreviousItem=(from z in dbArchive.AsQueryable()
 join tmp in (
 from y in dbArchive.AsQueryable()
 where y.LogId < newItemc.LogId && y.Id == newItem.Id
 group y by y.Id into g
 select new
 {
 LogId = g.Max(f => (int?)f.LogId) // this may help if database would return null
 }
 ) on z.LogId equals tmp.LogId 
 select z).FirstOrDefault() 
 }