Linq to SQL update multiple records in one query - sql

Given the code:
var q = db.TranslationProjectKeys.Where(c => c.ProjectID == forProject.ID);
foreach (var key in q)
{
key.Live = false;
}
db.SubmitChanges();
If I run the SQL server profiler it shows dozens of UPDATE.... SQL statements. I believe this would be considerably faster if this query was executed with one UPDATE statement:
UPDATE TranslationProjectKeys SET Live = 0 WHERE ProjectID = x
Is there a way to make the query execute in this way?
I'm wary of using db.ExecuteCommand("...") as I am aware the context can be cached which can cause some bugs.

You can use EntityFramework.Extended . You can execute multiple update.
For Example
var q = db.TranslationProjectKeys.Where(c => c.ProjectID == forProject.ID).Update(c => new TranslationProjectKey{ Live = false })

linq to sql does not have a built in mass update function (unless something has changed). you could just execute the command manually like
dataContext.ExecuteCommand("UPDATE TranslationProjectKeys SET Live = 0 WHERE ProjectID = {0}", x);
or if you wanted to get fancy, you could try implementing your own mass update functionality like this article shows, but it is MUCH more in depth and complicated (Though it IS possible to do)

Related

Update Oracle BLOB value in a batch

I'm trying to update a series of BLOB values using the following code. Note how we're not using Blob objects, but just calling setBytes.
try (PreparedStatement p = c.prepareStatement("UPDATE table SET data = ? WHERE id = ?") {
for (Map.Entry<String, byte[]> d : updates.entrySet()) {
p.setBytes(1, d.getValue());
p.setString(2, d.getKey());
p.addBatch();
}
p.executeBatch();
}
However, this is running really slowly (updating about 100 rows a second)
Is this the 'correct' way of doing these updates? Should we be using Blob objects? How do we do that to do these updates and new data inserts?
Is there any reason this might be running slowly?

Which is fast to fetch the data - Lambda expressions OR Linq query?

I am developing an web application and using mvc, entity framework, ado.net entity.
I want to know that which one is fast to fetch the data with some conditions :
1. Lambda Expression
2. Linq query
code snipped is below (in below code _dict is dictionary)
string fname = "", username = "", lname = "", mail = "";
if (_dict.ContainsKey("fname"))
fname = _dict["fname"].ToLower();
if (_dict.ContainsKey("username"))
username = _dict["username"].ToLower();
if (_dict.ContainsKey("lname"))
lname=_dict["lname"].ToLower();
if (_dict.ContainsKey("mail"))
mail = _dict["mail"].ToLower();
var _admins = db.AdminsTables.Where(x =>
x.firstname.ToLower().Contains(fname) &&
x.username.ToLower().Contains(username) &&
x.lastname.ToLower().Contains(lname) &&
x.useremail.ToLower().Contains(mail)).ToList();
OR
string fname = "", username = "", lname = "", mail = "";
if (_dict.ContainsKey("fname"))
fname = _dict["fname"].ToLower();
if (_dict.ContainsKey("username"))
username = _dict["username"].ToLower();
if (_dict.ContainsKey("lname"))
lname=_dict["lname"].ToLower();
if (_dict.ContainsKey("mail"))
mail = _dict["mail"].ToLower();
var _admins = (from record in db.AdminsTables
where record.firstname.ToLower().Contains(fname) && record.username.ToLower().Contains(username) && record.lastname.ToLower().Contains(lname) && record.useremail.ToLower().Contains(mail)
orderby record.id descending
select record).ToList();
Please suggest me which one is faster and is possible then give reason also.
In fact you can turn nearly every linq query into a lambda expression. When you working with linq-to-entities or entity-frame work, it doesn't matters if use linq querys or lambda expressions. What matters is the resulting SQL query.
So in your case the first code sample would be faster, because (like #karaxuna already mentioned) you added sorting to the query.
When performance is your focus, you should compare the linq query in code and a sql query in the database. For example:
write a SQL query for the result you want optimize it and look how long it takes
write a LINQ query in code for the same result, look how long it takes
If the SQL query is much faster, you should create a view, a stored procedure and call it from code.
If the measured times are nearly the same, it's up to you if use the LINQ query or create a view, a stored procedure and call it from code.
If the LINQ query is much faster, you should look at the generated SQL query it seems to better than your query.
As far as I experienced, there is only a significant performance difference when you query data which are distributed over multiple tables and need a lot of joins and/or sorting operations.

Entity Framework Count Discrepancy

I'm somewhat new to Entity Framework (4). I've been tracking down a bug in our software, and I've nailed it down the follow quirk. I'm curious if anyone can help me explain why these two Counts (dataCount and data2Count) would be different depending on the way I've invoked them. data2Count is correct and actually matches up with what I have in SQL.
using (var context = new Entities(ConnectionString))
{
var startDateTime = DateTime.Parse("10/1/2011");
var endDateTime = DateTime.Parse("12/31/2011 23:59");
var query = from data in context.vDATA
where data.ParentId == parentId &&
data.TimeStamp >= startDateTime &&
data.TimeStamp <= endDateTime
select data;
var data = query.ToList();
var dataCount = data.Where(x => x.TestType == 20).Count();
//dataCount is 162
var data2 = query.Where(x => x.TestType == 20);
var data2Count = data2.Count();
//data2Count is 198
}
Thanks.
Alright, I think I found and fixed what was happening - although I'm not sure I can explain internally how EF handles it... I found an article here: Entity framework result discrepancy for a database views that sounded like a similar issue. My data in SQL had several records who's fields were roughly identical. The only distinguishing field was TestType. But it was NOT marked as part of the key. Simply extending the key to include this field caused the Counts to match up correctly.
How is parentId getting set? Is it a variable declared outside of a loop this code fragment is running in? If so, this might be acting funky because of closure issues. This other question gives you a lot of information on how to address the closure issues.

LINQ display row numbers

I simply want to include a row number against the returned results of my query.
I found the following post that describes what I am trying to achieve but gives me an exception
http://vaultofthoughts.net/LINQRowNumberColumn.aspx
"An expression tree may not contain an assignment operator"
In MS SQL I would just use the ROWNUMBER() function, I'm simply looking for the equivalent in LINQ.
Use AsEnumerable() to evaluate the final part of your query on the client, and in that final part add a counter column:
int rowNo = 0;
var results = (from data in db.Data
// Add any processing to be performed server side
select data)
.AsEnumerable()
.Select(d => new { Data = d, Count = ++rowNo });
I'm not sure whether LINQ to SQL supports it (but it propably will), but there's an overload to the Queryable.Select method that accepts an lambda with an indexer. You can write your query as follows:
db.Authors.Select((author, index) => new
{
Lp = index, Name = author.Name
});
UPDATE:
I ran a few tests, but unfortunately LINQ to SQL does not support this overload (both 3.5sp1 and 4.0). It throws a NotSupportedException with the message:
Unsupported overload used for query
operator 'Select'.
LINQ to SQL allows you to map a SQL function. While I've not tested this, I think this construct will work:
public partial class YourDataContext : DatContext
{
[Function(Name = "ROWNUMBER")]
public int RowNumber()
{
throw InvalidOperationException("Not called directly.");
}
}
And write a query as follows:
from author in db.Authors
select new { Lp = db.RowNumber(), Name = author.Name };

SQL server profiler not showing LINQ To Sql queries

I am trying to view SQL generated by Linq to SQL in the SQL Server Profiler (2005).
I can see the sql sent to the server from anything except for linq to sql.
I'm betting that I need to change event selections for the trace, but not sure what else to select.
I am currently only selecting this:
SQL:StmtCompleted - TextData & SPID
I don't want to use data context logging nor the SQL Debug Visualizer. I need to use the profiler.
Why can I not see the LINQ to SQL queries?
Thanks.
EDIT
I added SQL:BatchCompleted and that hasn't helped.
EDIT 2
I added the event RPC:Completed which is found under the Stored Procedures category in event selection. This worked!
You need RPC call - the queries are executed as exec_sql.
Are you including enough of the options in the SQL Profiler to see the BatchCompleted events, too?
Marc
There is also an option in the data context class to enable log in the client side. When log is enabled is possible to see the queries.
See this link:
http://www.davidhayden.com/blog/dave/archive/2007/08/17/DataContextLogLoggingLINQToSQLOutputConsoleDebuggerOuputWindow.aspx
Had the same problem and none of the solutions above worked for me.
What worked for me was adding ToList() enumerator to the query.
Before:
var data = null == id ?
(from ...
select new
{
...
})
:
(from ..
select new
{
...
});
After:
var data = null == id ?
(from ...
select new
{
...
}).ToList()
:
(from ..
select new
{
...
}).ToList();
foreach (var obj in data)
{
xxx = obj.somename; --> now you can see the sql query in Profiler