|
That's the the great thing about LINQ: you can write the most complex operations in a single statement so when it fails you have no idea where the problem is.
|
|
|
|
|
These are the tables :
MyObj1:
Id name
2 name1
7 name7
8 name8
Child1:
ID ParentID TP Quantity Value
1 2 2 7 9
2 7 2 20 10
3 7 2 8 11
( ParentID is the forign key for child1 related to ID field on MyObj )
So the problem is on my query structure or in the tables ?
|
|
|
|
|
Based on that data, you don't have any Child1 rows for the MyObj1 row with ID 8. Since that row is included in your outer query (where t1.id > 6 ), you're trying to take the Sum of an empty sequence.
It seems that the EF query is returning NULL from the database, and then trying to convert that to a Decimal value. This issue is discussed on Matteo Tontini's Blog[^], albeit for C#.
Try casting the properties to Decimal? / Nullable(Of Decimal) before summing them.
Nullable Value Types (Visual Basic) - MSDN[^]
Dim lst = (From t In context.MyObj1 where t1.id>6 Select New With { _
.Parent = t, _
.sash = t.child1.AsQueryable.Where(Function(t2) t2.tp = 2).Sum(Function(t3) DirectCast(t3.quantity, Decimal?)), _
.vlh = t.child1.AsQueryable.Where(Function(t3) t3.tp = 2).Sum(Function(t3) DirectCast(t3.value, Decimal?)) _
}).ToList
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
I try your code , but now I get an error on design time : Decimal Value cannot be converted to Decimal?
|
|
|
|
|
That's annoying - C# just uses (decimal?)t.value , but it seems VB.NET can't cope with that.
You can either use the constructor:
Dim lst = (From t In context.MyObj1 where t1.id > 6 Select New With { _
.Parent = t, _
.sash = t.child1.AsQueryable.Where(Function(t2) t2.tp = 2).Sum(Function(t3) New Decimal?(t3.quantity)), _
.vlh = t.child1.AsQueryable.Where(Function(t3) t3.tp = 2).Sum(Function(t3) New Decimal?(t3.value)) _
}).ToList
Or explicitly specify the type argument for the Sum method:
Dim lst = (From t In context.MyObj1 where t1.id > 6 Select New With { _
.Parent = t, _
.sash = t.child1.AsQueryable.Where(Function(t2) t2.tp = 2).Sum(Of Decimal?)(Function(t3) t3.quantity), _
.vlh = t.child1.AsQueryable.Where(Function(t3) t3.tp = 2).Sum(Of Decimal?)(Function(t3) t3.value) _
}).ToList
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
I try both your methods :
The first produce this error on runtime :
An unhandled exception of type 'System.NotSupportedException' occurred in EntityFramework.SqlServer.dll
Additional information: Only parameterless constructors and initializers are supported in LINQ to Entities.
The second method, produce this error on design time :
Error 103 Overload resolution failed because no accessible 'Sum' accepts this number of type arguments.
|
|
|
|
|
Sorry, I forgot you need to specify the source type parameter as well. Something like:
t.child1.AsQueryable.Where(Function(t2) t2.tp = 2).Sum(Of Child1, Decimal?)(Function(t3) t3.quantity)
where Child1 is the name of your class.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Hello !
I'm using this expression :
t.child1.AsQueryable.Where(Function(t2) t2.tp = 2).Sum(Function(t3) CType(t3.quantity, System.Nullable(Of Decimal)))
now I'm not getting any error message , but I have another problem :
As you have noted on your previous posts , the item on MyObj1 with id=8 has no child1 items. But for this item I need that the sums to return 0 in the query , but instead I have no value at all for this item. what should I do ?
Thank you !
|
|
|
|
|
Add a .GetValueOrDefault() call to the end:
t.child1.AsQueryable.Where(Function(t2) t2.tp = 2).Sum(Function(t3) CType(t3.quantity, System.Nullable(Of Decimal))).GetValueOrDefault()
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Hello !
I try your solution but I get a runtime error :
An unhandled exception of type 'System.NotSupportedException' occurred in EntityFramework.SqlServer.dll
Additional information: LINQ to Entities does not recognize the method 'System.Decimal GetValueOrDefault()' method, and this method cannot be translated into a store expression.
|
|
|
|
|
OK, try moving the .GetValueOrDefault() call to a second Select , with an .AsEnumerable() call to make sure it runs in code rather than SQL:
Dim query = From t In context.MyObj1 where t1.id > 6 Select New With { _
.Parent = t, _
.sash = t.child1.AsQueryable.Where(Function(t2) t2.tp = 2).Sum(Function(t3) CType(t3.quantity, System.Nullable(Of Decimal))), _
.vlh = t.child1.AsQueryable.Where(Function(t3) t3.tp = 2).Sum(Function(t3) CType(t3.value, System.Nullable(Of Decimal))) _
}
Dim lst = query.AsEnumerable().Select(Function(t) New With { _
.Parent = t.Parent, _
.sash = t.sash.GetValueOrDefault(), _
.vlh = t.vlh.GetValueOrDefault() _
}).ToList()
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Hi, im doing a user profile, and i'd like to include the option which will allow to upload a picture from the computer
|
|
|
|
|
Upload it to where? Is this something to do with Visual Basic or a web based issue?
|
|
|
|
|
It is no issue at all, im creating a profile, and i want to create this option, that when u run the application, you will be able to include a picture to your profile, that you will browse form the computer.
I did some googling, and saw that most the codes for this case include "openfiledialog", link label.. and i just cannot come to an end with this, because i just started learning.
|
|
|
|
|
Member 11447662 wrote: most the codes for this case include "openfiledialog", link label. Quite possibly they do, but that still does not explain what your problem is, or where you plan to upload these images to, or indeed how you plan to upload them. I suggest you study http://www.codeproject.com/Messages/1278601/How-to-get-an-answer-to-your-question.aspx[^], and come back with some more specific details. Saying "I want to do X", does not really help us to help you.
|
|
|
|
|
Hello !
I'm using entity framework , and I have several cases where I should run a query than return some parent items , and after I display these parents and the related children in one report.
I want to know which of these methods have the better performance : ( or is there any other better method ??? )
Method1: (the childs collection are loaded later , using lazy loading)
Dim lista as IQueryable(Of MyObj) = (From t In context.MyObjs Where(..condition..) select t).Tolist
Method2:
Dim lista as IQueryable(Of MyObj) = (From t In context.MyObjs Where(..condition..) _
.Include(Function(t2) t2.Childs1) _
.Include(Function(t2) t2.Childs2) _
.Include(Function(t2) t2.Childs2.Child22) _
.Include(Function(t2) t2.Childs1.Childs11) _
.Include(Function(t2) t2.Childs1.Childs12) _
Select t).ToList
Method3:
Dim lista as IQueryable(Of MyObj)
Dim lst= (From t2 In context.MyObjs Where(..condition..) Select New with _
{ .Parent=t2
.ch1=t2.Childs1 _
.ch2=t2.Childs2 _
.ch21=t2.Childs2.Child21) _
.ch11=t2.Childs1.Childs11) _
.ch12= t2.Childs1.Childs12 _
).ToList
lista=lst.Select(Function(t2) t2.parent)
I noticed that the first method cause the report to open very slow.
Also I read somewhere that Include() cause repeat of parent items , lik in this example :
For example: Master -> Details. Say, master has 100 rows, Details has 5000 rows (50 for each master).
If you lazy-load the details, you return 100 rows (size: master) + 5000 rows (size: details).
If you use .Include("Details"), you return 5000 rows (size: master + details). Essentially, the master portion is duplicated over 50 times.
I don't know the logic when use Projections like in the third mode ? Are the master rows duplicated ?????
But anyway I want a professional opinion in general for the three methods.
Thank you !
|
|
|
|
|
Time it, and compare it to a SQL query.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Sorry , but what I need is not timing a specific case , but a general opinion from a person that knows how these method works.
|
|
|
|
|
The problem with that question is we don't know how your database is setup so it's impossible to make that determination.
For example, I had an EF query that I wasn't happy about the performance with and, after a couple of well thought out indexes were put it in, query performance increased considerably.
|
|
|
|
|
ok , but in general :
- It's true that master rows are repeated when using Include () ( like the example I posted before )?
- The same questions for Projections ?
Thank you !
|
|
|
|
|
No, it's not.
If you want to find out what really happens, set a breakpoint on the code on the line that sets up the query. Hover the mouse over the variable that holds the query. It'll show you the SQL that it's going to execute. Just click on the SELECT statement and you can swipe over it and copy the query SQL. Paste that into a SQL Server Manager query window and you can see exactly what the query returns, every row and column.
You can even use the Query Profiler in Server Manager to see the execution plan and how long it takes the database to execute it.
|
|
|
|
|
|
The more Includes you put in, the more data has to be returned from the server.
If you have related tables, such as a one-to-many, in the result, the database will return the "one" record for every related child record that comes back. That's standard behavior for the database engine.
EF will only re-hydrate the parent record into an object once, but will have to re-hydrate each child record, for every Include you put in the query. The more Includes, the more work EF has to do. I would have thought that would be an obvious performance hit.
|
|
|
|
|
Thank you , but what about the case with Projection ?
|
|
|
|
|
That's even MORE work EF has to do!
|
|
|
|