Entity Framework much slower than SSMS - performance

I have a super simple query
select * from documents where id= 50189
This returns one pretty heavy row from SQL Server. (about 30 MB). Execution time is between 30-120 seconds
but when I run the query via EF, it takes more than 10 minutes!
how can that be? and how can that be fixed?
here's the pretty basic EF code:
Dim d = GetSystemContext()
d.CommandTimeout = TimeSpan.FromMinutes(15)
Dim qry = d.Set(Of Document).AsNoTracking
Dim id = 50189
Dim a = qry.Where(Function(x) x.ID = id)
Dim cmd = a.GetCommand
Dim b = a.FirstOrDefault
any ideas anybody?
TIA!

Related

strange behaviour of linq usage

I have two tables (t1 and t2) and I select two fields from this tables (f1 and f2).
The list Queries contains the selected data. In this case there are 2 entry with 2 rows.
This is the code:
Dim FieldIndexes As New List(Of Integer)
Dim Queries As New List(Of IEnumerable(Of Object()))
For i = 0 To _SqlSyntaxChecker.QueriedTables.Count - 1
FieldIndexes.Clear()
For j = 0 To _SqlSyntaxChecker.DataFields.Count - 1
If _SqlSyntaxChecker.QueriedTables(i).TableName = _SqlSyntaxChecker.DataFields(j).TableName Then FieldIndexes.Add(_SqlSyntaxChecker.DataFields(j).FieldIndexInDataTable)
Next
Dim query = _SqlSyntaxChecker.QueriedTables(i).Rows.Select(Function(Row) FieldIndexes.Select(Function(FieldIndex) Row.Item(FieldIndex)).ToArray)
Queries.Add(query)
For Each item In Queries(i)
_OutputDataTable.Rows.Add(item)
Next
Next
And this is the result:
As you see, everything is ok, I expected this result (it is now not important, that I have on the image 4 rows in one column).
Originally, I wanted to populate the _OutputDataTable outside the for cykle, like so:
Dim FieldIndexes As New List(Of Integer)
Dim Queries As New List(Of IEnumerable(Of Object()))
For i = 0 To _SqlSyntaxChecker.QueriedTables.Count - 1
FieldIndexes.Clear()
For j = 0 To _SqlSyntaxChecker.DataFields.Count - 1
If _SqlSyntaxChecker.QueriedTables(i).TableName = _SqlSyntaxChecker.DataFields(j).TableName Then FieldIndexes.Add(_SqlSyntaxChecker.DataFields(j).FieldIndexInDataTable)
Next
Dim query = _SqlSyntaxChecker.QueriedTables(i).Rows.Select(Function(Row) FieldIndexes.Select(Function(FieldIndex) Row.Item(FieldIndex)).ToArray)
Queries.Add(query)
Next
For Each q In Queries
For Each item In q
_OutputDataTable.Rows.Add(item)
Next
Next
But as you see, the result is wrong:
The result should be the same.
What can cause this?
Your query is linked to i field (using closures). But queries are execute after first cycle, so i already have its last value when query is executed.
You can check "Access to modified closure" topic over internet (mainly it's about delegates but actually same thing works for expression trees).

order results of linq query by multiple items

using the following query
Dim allEvents As New List(Of Events)
Dim digits = "1 2 3 4 5 6 7 8 9 0".Split()
Dim results = (From t In ctx.events
Where t.date = todaysdate.Date AndAlso
Not digits.Any(Function(d) (t.symbol.Contains(d)))
Order By t.time
Select New With {
t.symbol,
t.date, t.time,
t.description,
t.domestic_call_num,
t.web_url})
If results.Count > 0 Then
For x As Integer = 0 To results.Count - 1
Dim newevent As New Events
With newevent
.CompanySymbol = results(x).symbol
.EventDate = results(x).date
.EventTime = Left(results(x).time.ToString(), 5)
.EventDescription = results(x).description
If results(x).domestic_call_num IsNot Nothing Then
.DialInNumber = results(x).domestic_call_num
Else
.DialInNumber = ""
End If
If results(x).web_url IsNot Nothing Then
.WebCastUrl = results(x).web_url
Else
.WebCastUrl = ""
End If
End With
allEvents.Add(newevent)
Next
Return allEvents
I get the results I want, but i'd like to further order them by description and time
I tried the following, which should have worked
Dim results = (From t In ctx.events
Where t.date = todaysdate.Date AndAlso
Not digits.Any(Function(d) (t.symbol.Contains(d)))
Order By t.time
Group By t.description
Select New With {
t.symbol,
t.date, t.time,
t.description,
t.domestic_call_num,
t.web_url})
I also tried ThenBy which the compiler didnt like. Any help on how to accomplish this would be appreciated. Essentially I want a sort order of time then description then symbol.
When using integrated syntax, you'd write this as:
Order By t.time, t.description
Select New With {
...
For details, see the Query Expression Examples for ThenBy.
You can try ordering your items at the end of the query like that :
Dim results = (From t In ctx.events
Where t.date = todaysdate.Date AndAlso
Not digits.Any(Function(d) (t.symbol.Contains(d)))
Select New With {
t.symbol,
t.date, t.time,
t.description,
t.domestic_call_num,
t.web_url}).OrderBy(Function(r) r.time)
.ThenBy(Function(r) r.description)
It's probably faster to do it in the query tho.

How does using (RecordSet).EOF on If statements work?

I have these lines of code, from vb6 trying to migrate them to vb.net.
What´s the logic behind them?
RegFileHf.CommandText = "Select dayspassed from Config"
Set UltHf = RegFileHf.Execute
If Not UltHf.EOF Then
someDate = Date - UltHf.Fields("dayspassed")
Else
someDate = Date - 180
End If
Does the If statement executes multiple time until end of file?
Does the else part comes in only when there´s no rows on my SQL query?
(Can you guys recommend good books to learn VB.NET so I can stop making newbie questions?)
Thanks in advance.
EOF condition mean that you get in the end of data .. that mean no row return
So, if there's (a) rows it will fire -> someDate = Date - UltHf.Fields("dayspassed")
If there's no row it fire -> someDate = Date - 180
Something like that ..
In VB.NET
Dim query = "Select dayspassed from Config"
Dim dc = New OleDbCommand(query, connection)
Dim rows As OleDb.OleDbDataReader
rows = dc.ExecuteReader
If rows.HasRows Then
'...... someDate = Date - rows.item("dayspassed")
else
'...... someDate = Date - 180
End If
Book --> try Google to find

deleting a record in linq to sql (vb.net) what is wrong with my code?

I am getting the correct Employee Id in the VarEmpID variable. When I click on delete
It is giving me
Unable to cast object of type 'System.Data.Linq.DataQuery`1[my name space]' to type 'namespace'.
enter code here
Protected Sub radGrid1_DeleteCommand(ByVal source As Object, ByVal e As GridCommandEventArgs) Handles radGrid1.DeleteCommand
Dim VarEmpId As String = (CType(e.Item, GridDataItem)).OwnerTableView.DataKeyValues(e.Item.ItemIndex)("EmpId").ToString()
Using dc1 As New EmployeesDataClassesDataContext()
Dim EmployeeEntry = (From p In dc1.Employees
Where (p.EmpId = VarEmpId)
Select p)
dc1.Employees.DeleteOnSubmit(EmployeeEntry)
dc1.SubmitChanges()
Dim queryResults = (From queryItem In EmployeeEntry Select queryItem).ToList()
If queryResults.Any Then
radGrid1.DataSource = queryResults
radGrid1.DataBind()
End If
End Using
End Sub
dc1.Employees.DeleteOnSubmit(EmployeeEntry)
That method expects an Employee instance. Instead, you passed in an employee query.
Dim EmployeeEntry = ( query )
This is a query, not an entry. Consider calling Enumerable.First to get the first result of the query, and then deleting that.
Modified added Dim EmployeeEntry = (From p In dc1.Employees Where (p.EmpId = VarEmpId) Select p).singleorDefault() After that commented out the queryresults part and binded data again it solved my problem. – SmilingLily

Need help with designing a query in ELinq

This is my query:
Dim vendorId = 1, categoryId = 1
Dim styles = From style In My.Context.Styles.Include("Vendor") _
Where style.Vendor.VendorId = vendorId _
AndAlso (From si In style.StyleItems _
Where si.Item.Group.Category.CategoryId = _
categoryId).Count > 0 _
Distinct
I have the feeling that I can improve the performance, cuz the above query is (correct me if I am wrong) performs 2 round-trips to the server; 1 time by the Count and then when it's executed.
I want to send this Count thing to the DB so it should be only one round trip to the server.
Even it's not the exact thing, this is actually what I need:
SELECT DISTINCT Style.*
FROM Style INNER JOIN
Vendor ON Style.VendorId = Vendor.VendorId INNER JOIN
StyleItem ON Style.StyleId = StyleItem.StyleId INNER JOIN
Item ON StyleItem.ItemId = Item.ItemId INNER JOIN
[Group] ON Item.GroupId = [Group].GroupId INNER JOIN
Category ON [Group].CategoryId = Category.CategoryId
WHERE (Style.VendorId = #vendorid) AND (Category.CategoryId = #CategoryId)
I wish I could use this SPROC (i.e. function import etc.), but I need to Include("Vendor"), which constraints me to do it with Linq.
Any kind of suggestion will be really welcommed!
It is probably not doing two trips to the database. It will get optimized before it is executed, and nothing gets executed until you try the read the data.
Normally I check the SQL that is created using SQL Profiler. I have also found LinqPad to be very usefull.

Resources