Hi,
I've encountered a strange exception:
I'm trying to do a rather innocent sum:
decimal total = myEntity.Lines.Sum(l => l.Amount.GetValueOrDefault());
This throws an exception:
L'exception System.InvalidCastException s'est produite
Message="Unable to cast null value to System.Decimal; use System.Decimal? instead."
Source="Xtensive.Core"
StackTrace:
à Xtensive.Core.Tuples.Tuple.GetValueOrDefault[T](Int32 fieldIndex)
à lambda_method(ExecutionScope , Object[] , Tuple , ItemMaterializationContext )
à System.DelegateBindExtensions.<>c__DisplayClassa`4.<Bind>b__9(T2 arg2, T3 arg3)
à Xtensive.Storage.Linq.Materialization.MaterializationHelper.<>c__DisplayClass4`1.<Materialize>b__3(Tuple tuple)
à System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
à System.EnumerableExtensions.<Batch>d__27`1.MoveNext()
à System.EnumerableExtensions.<ApplyBeforeAndAfter>d__2f`1.MoveNext()
à Xtensive.Storage.TransactionalExtensions.<ToTransactional>d__0`1.MoveNext()
à System.Linq.Enumerable.<SelectManyIterator>d__14`2.MoveNext()
à System.Linq.Enumerable.First[TSource](IEnumerable`1 source)
à lambda_method(ExecutionScope , Object[] , IEnumerable`1 , Dictionary`2 , ParameterContext )
à System.DelegateBindExtensions.<>c__DisplayClass13`5.<Bind>b__12(T2 arg2, T3 arg3, T4 arg4)
à Xtensive.Storage.Linq.TranslatedQuery`1.Execute(ParameterContext parameterContext)
à Xtensive.Storage.Linq.QueryProvider.Execute[TResult](Expression expression)
à System.Linq.Queryable.Sum[TSource](IQueryable`1 source, Expression`1 selector)
I've tried to create a small sample but naturally the sample runs just fine... ;)
Any thought on this problem?
Updated at 04.05.2010 7:36:49
Hello,
Here is the file version of Xtensive.Storage : 1.0.4870.60138 (latest 4.2 release)
For the model, I will try to build a model reproducing the bug, but I've not been successful for now.
Regards,
Updated at 04.05.2010 7:58:26
Ok, I found the problem: it happens when doing the sum of an empty Entiset<t> on a Nullable type column
Model:
[Serializable]
[HierarchyRoot]
public class MyEntity : Entity
{
[Field, Key]
public int Id { get; private set; }
[Field, Association(PairTo = "Owner")]
public EntitySet<Line> Lines { get; private set; }
}
[HierarchyRoot]
public class Line : Entity
{
[Field, Key]
public int Id { get; private set; }
[Field]
public MyEntity Owner { get; set; }
[Field]
public decimal? Amount { get; set; }
}
Test code:
using (Session.Open(domain))
{
using (var transactionScope = Transaction.Open())
{
var myEntity = new MyEntity();
transactionScope.Complete();
}
}
using (Session.Open(domain))
{
using (var transactionScope = Transaction.Open())
{
MyEntity myEntity = Query.All<MyEntity>().FirstOrDefault();
Console.WriteLine("Sum = " + myEntity.Lines.Sum(l => l.Amount.GetValueOrDefault()));
transactionScope.Complete();
}
}
Updated at 04.05.2010 8:23:59
Yes this helps : but I disagree with your solution.
First problem:
myEntity.Lines.Sum(l => l.Amount.GetValueOrDefault()) is of type decimal.
So I can't use the ?? operator (decimal can not contains null)
Second problem:
This is inconsistent with the behavior of standard LinqToObject Sum()
Sample:
class Test
{
public decimal? Amount { get; set; }
}
I create an empty list of objects and sum it (like previous sample but without DO)
List<Test> emptyList = new List<Test>();
decimal sum2 = emptyList.Sum(l => l.Amount.GetValueOrDefault());
Console.WriteLine("Sum (decimal) = " + sum2);
The result is 0.
For me this is a (minor) bug, and you should correct this particular case to get a true complete LINQ implementation.
Do you agree?
This thread was imported from our support forum. The original discussion may contain more detailed answer.
asked
May 03 '10 at 16:07
olorin
358●87●87●92
Hello,
Could you please post a subset of your domain model which includes types, taking part in the query?
Also, the file version of DataObjects.Net will assemblies be helpful.