Get multiple values from querying db with entity framework - sql

I've been thinking this for a while. Is there an easy way to use the result querying a database twice without storing the result of the query in some variable? Say I have a
string ResearchAdmin;
where I want to put the 'FirstName' and 'Surname' found in 2 different columns in a 'ProjectResearcher' table in the database. Can I query the database just once (using say entity framework), and get both columns without storing the entire table's data.
To illustrate my point, doing the code below will I think query the database twice, once to get the 'FirstName', once to get the 'Surname':
ResearchAdmin = db.ProjectResearcher.FirstOrDefault(r => r.ProjectId == project.ProjectId).Researcher.FirstName + " " + db.ProjectResearcher.FirstOrDefault(r => r.ProjectId == project.ProjectId).Researcher.Surname
To run the query once I can do the following:
Researcher researchAdmin = db.ProjectResearcher.FirstOrDefault(r => r.ProjectId == project.ProjectId).Researcher;
String researchAdminName = researchAdmin.FirstName + " " + researchAdmin.Surname;
What I'm wondering is if I can do the first option somehow without querying the database twice.

You could do something like this:
String researchAdminName = db.ProjectResearcher.Where(r => r.ProjectId == project.ProjectId)
.Select(r => r.FirstName + " " + r.Surname).FirstOrDefault();
Just have to be a little careful that whatever you are putting into the select statement is supported by linq to entities, but simple string concatenation is.

Thewads answer looks correct and it will give you what you need.
An alternative:
Wrap logic in Stored Proc (certainly an overkill here) but for more complex manipulation its prob. better as SQL server will have a cached plan and will be faster.

Related

MS Access SQL Switch Function

I have several tables with the same data structure (they're filled with a bunch of stuff, in separate .accdb files to account for the 2GB limit) and need to retrieve info from one of them based on a field in a form.
Upon researching I came up with the following, but it won't seem to work.
SELECT MyNumber, MyName, MyPage, MyDrawing
FROM Switch([Forms]![View_Info]![Contract] = "Contract1", "tblContract1", [Forms]![View_Info]![Contract] = "Contract2", "tblContract2")
WHERE (MyNumber = [Forms]![View_Info]![MyNumber])
Syntax error in FROM clause.
In this example I only used 4 fields and 2 tables but in fact there are around 9 tables and 20 fields in each that I wish to retrieve.
Can someone shed some light on this? I have a really hard time with SQL, so I apologize if this is quite basic.
Thanks in advance, Rafael.
You cannot return the table name from a function in the SQL FROM clause. If your table is determined dynamically, then you must build the SQL command string dynamically.
Dim tableName As String, sql As String
tableName = Switch(...)
sql = "SELECT ... FROM [" & tableName & "] WHERE ..."
As #forpas explains in his answer, you can use a UNION query, but this will always query all the tables. Since the filter is not based on a table column, the filtering will occur on the client side, i.e. in your application.
Try this UNION:
SELECT MyNumber, MyName, MyPage, MyDrawing
FROM tblContract1
WHERE (MyNumber = [Forms]![View_Info]![MyNumber]) AND [Forms]![View_Info]![Contract] = "Contract1"
UNION
SELECT MyNumber, MyName, MyPage, MyDrawing
FROM tblContract2
WHERE (MyNumber = [Forms]![View_Info]![MyNumber]) AND [Forms]![View_Info]![Contract] = "Contract2"
Each query of the UNION contains in the WHERE clause the condition:
[Forms]![View_Info]![Contract] = "Contract?"

Storing query as a int to check to see if more than one exists

The code is suppose to check my database to see if there are duplicates of activityName existing if that query runs I am suppose to get an error stating that the activity name is taken else if there isn't any activity name in that database with the same name then the activity name would be inserted into the database. Im suppose to execute the query and get the result as an Integer then use the result in the if and else to see if result>0 in the database
var queryCount= 'SELECT COUNT (activityName) FROM dataEntryTb WHERE activityName = "'+an+'" ';
tx.executeSql(queryCount,[]);
if(queryCount > 0){
navigator.notification.alert("Activity Name Taken");
}else{
Not sure what's the issue exactly but it should work fine. You can consider changing it like
var queryCount= "SELECT 1 FROM dataEntryTb WHERE activityName = '" + an + "'";
Again, consider using parameterized query instead of string concatenation to avoid SQL Injection (if an is coming as user input)

Dynamically create sql where condition on textbox entry

I am working on a C# desktop application. I want to create a search functionality. Now the problem is that i am using around 8 textboxes. Different permutations of textboxes could be populated and the resulting 'sql where' condition should only include those textboxes values which are not null. Now one pathetic way is to use a zillion 'if and else' which obviously is laborious. Any other way to do this?
You need just one query with filled WHERE to use all parameters like this
select ...
from ...
WHERE
(firstNameColumn=:firstNameParam or :firstNameParam is null)
AND (lastNameColumn=:lastNameParam or :lastNameParam is null)
AND (...)
I would like to make a point of first checking is the paramtere null, then use it to compare with column values.
Since you are generating query in C#, try old-Chinese approach from Ming period of using default condition where 1=1 just to avoid checking did you already had first condition :)
string query = "select ... from ... join ... on ... where 1=1";
//suposedly you have value of one search box in variable called "item_name"
if(string.IsNullOrWhiteSpace(item_name) == false)
{
query += " and Order_Line.Name ='" + item_name + "'";
}
and so on for other fields.
What you are trying to do in order to avoid ifs is not really a good approach. Look at this:
string query = " select ... where Order_Line.Name = '" + item_name + "'";
What will be the resulting string if item_name is actually null?
EDIT: the resulting query would be
where Order_Line.Name = '' or Order_Line.Name is null
which is not what you want. You want every row if that search field is empty, menaing it shouldn't have anu effect on search. That's why you need condition to see will you include this column in where clause in the first place.

Report Builder 3.0 underlying SQL

I have a report builder 3.0 report that has several parameters on it. Specifically, an account number (Defined as char(12) in the database). The database is a vendor supplied database, so I have zero control over the database schema.
My question is when I have a free form parameter for account id, how is that transformed into the query sent to the sql database?
The way I handle these free form fields is that I have a user defined function:
Public Function ConvertStringtoArray(sourceString as String) As string()
Dim arrayOfStrings() As String
Dim emptyString as String = " "
If String.IsNullOrEmpty(sourceString) Then
arrayOfStrings = emptyString.Split(",")
Else
arrayOfStrings = sourceString.Replace(" ", "").Split(",")
End If
return arrayOfStrings
End Function
And the parameter is defined as:
#AcctList = code.ConvertStringToArray(Parameters!AcctList.Value)
The sql query has this in the where clause:
Ac.Account_ID In (#AcctList)
My question is how does it build the In Clause. Will it literally be something like:
Where Ac.Account_ID In (N'Acct1',N'Acct2').
I'm thinking it is, and the reason I think it's important is the query when I am running it in SSMS will run in less than 1 Second if my where clause has Where Ac.Account_ID In ('TGIF').. But it will take 13+ Seconds if I have Where Ac.Account_ID In (N'TGIF'). The total dataset returned is only 917 Rows.
The database I am querying is a 2008 R2 SP2, with the compatibility set to SQL 2008.
You assumption is correct for the predicate of 'where thing in (#parameter)' actually being 'where thing in ('value1', 'value2', etc). Provided that #parameter allows multiple values. However you can tie a parameter to a query as well as using code. You can have a dataset other than your main dataset like a simple 'Select value from values' where the values would be a table of values needed for a parameter choice. This is often much more efficient unless you have to do a string split.

Converting Sql query (update table set ....) to linq ( var m = ...)

I am trying to write a linq query in my Database.cs file. I find it difficult. Is there any tool to convert sql to linq? I tried linqer but it is no good. Or could you help me in writing the following query in linq.
update table
set field1='R',
field2='" + DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss") + "',
field3 = '" + util.CleanStringInput(value1) + "'
where field1 = 'P'
and field3 = '" + value2 + "'
and field4 = (select max(field5)
from table2
where field6='" + value2 + "')
The easiest way would be to fetch the entities, set the properties and then save changes:
var maxFromTable2 = context.YourTables2.
Where(t2 => t2.field6 == value2).
Max(t2 => t2.field5);
var entitiesToUpdate = context.YourTables.
Where(t => t.field1 == "P" &&
t.field3 == value2 &&
t.field4 == maxFromTable2).
ToList();
foreach (var entityToUpdate in entitiesToUpdate)
{
entityToUpdate.field1 = "R";
entityToUpdate.field2 = DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss");
}
context.SaveChanges();
NOTE: It is not clear from your question what table you are updating, so I assume by default that it is a table different from table2. It could help if you indicate whether you are using LINQ to SQL or Entity Framework (LINQ to Entitites). The current syntax is for EF.
LINQ to SQL/EF are intended to hydrate objects and operate on those, saving the changes. It is not intended as a replacement for batch operations. If you use EF/LINQ to SQL in this case, you will be issuing n+1 requests to the database: 1 to select the records you are going to change and a separate request for each row (object) you are updating. With a small data set, this may be managable, but if you have any kind of volume, keeping this in a stored proc using a single Update statement may be a better option.