What is best approach to get sql data from C# - c#

I'm trying to find optimal (fast vs easiest) way to access SQL Server code thru code in C#.
As I was learning from books I've encountered multiple suggestions usually telling me to do it via drag and drop. However since I wanted to do it in code first approach was to get data by column numbers, but any reordering in SQL Query (like adding/removing columns) was pain for me to fix.
For example (don't laugh, some code is like 2 years old), I even coded special function to pass sqlQueryResult and check if it's null or not):
public static void exampleByColumnNumber(string varValue) {
string preparedCommand = #"SELECT TOP 1 [SomeColumn],[SomeColumn2]
FROM [Database].[dbo].[Table]
WHERE [SomeOtherColumn] = #varValue";
SqlCommand sqlQuery = new SqlCommand(preparedCommand, Locale.sqlDataConnection);
sqlQuery.Prepare();
sqlQuery.Parameters.AddWithValue("#varValue) ", varValue);
SqlDataReader sqlQueryResult = sqlQuery.ExecuteReader();
if (sqlQueryResult != null) {
while (sqlQueryResult.Read()) {
string var1 = Locale.checkForNullReturnString(sqlQueryResult, 0);
string var2 = Locale.checkForNullReturnString(sqlQueryResult, 1);
}
sqlQueryResult.Close();
}
}
Later on I found out it's possible thru column names (which seems easier to read with multiple columns and a lot of changing order etc):
public static void exampleByColumnNames(string varValue) {
string preparedCommand = #"SELECT TOP 1 [SomeColumn],[SomeColumn2]
FROM [Database].[dbo].[Table]
WHERE [SomeOtherColumn] = #varValue";
SqlCommand sqlQuery = new SqlCommand(preparedCommand, Locale.sqlDataConnection);
sqlQuery.Prepare();
sqlQuery.Parameters.AddWithValue("#varValue) ", varValue);
SqlDataReader sqlQueryResult = sqlQuery.ExecuteReader();
if (sqlQueryResult != null) {
while (sqlQueryResult.Read()) {
string var1 = (string) sqlQueryResult["SomeColumn"];
string var2 = (string) sqlQueryResult["SomeColumn2"];
}
sqlQueryResult.Close();
}
}
And 3rd example is by doing it by column names but using .ToString() to make sure it's not null value, or by doing If/else on the null check.
public static void exampleByColumnNamesAgain(string varValue) {
string preparedCommand = #"SELECT TOP 1 [SomeColumn],[SomeColumn2], [SomeColumn3]
FROM [Database].[dbo].[Table]
WHERE [SomeOtherColumn] = #varValue";
SqlCommand sqlQuery = new SqlCommand(preparedCommand, Locale.sqlDataConnection);
sqlQuery.Prepare();
sqlQuery.Parameters.AddWithValue("#varValue) ", varValue);
SqlDataReader sqlQueryResult = sqlQuery.ExecuteReader();
if (sqlQueryResult != null) {
while (sqlQueryResult.Read()) {
string var1 = (string) sqlQueryResult["SomeColumn"].ToString();
DateTime var2;
DateTime.TryParse(sqlQueryResult["SomeColumn2"].ToString());
int varInt = ((int) sqlQueryResult["SomeColumn3"] == null ? 0 : (int) sqlQueryResult["SomeColumn3"];
}
sqlQueryResult.Close();
}
}
Please bare in mind that I've just created this for sake of this example and there might be some typos or some slight syntax error, but the main question is which approach is best, which is the worst (I know first one is the one that I dislike the most).
I will soon have to start / rewriting some portion of my little 90k lines app which has at least those 3 examples used widely, so i would like to get best method for speed and preferably easiest to maintain (hopefully it will be same approach).
Probably there are some better options out there so please share?

It seems you may be looking at old books. If you're going to do it the "old fashioned way", then you should at least use using blocks. Summary:
using (var connection = new SqlConnection(connectionString))
{
using (var command = new SqlCommand(commandString, connection))
{
using (var reader = command.ExecuteReader())
{
// Use the reader
}
}
}
Better still, look into Entity Framework.
Links: Data Developer Center

If it's easy you're looking for, you can't do any better than Linq-to-SQL:-
http://weblogs.asp.net/scottgu/archive/2007/05/19/using-linq-to-sql-part-1.aspx
If your SQL database already exists, you can be up-and-running in seconds.
Otherwise, I agree with John.

you should have a look into these tutorials,
[http://www.asp.net/learn/data-access/][1]
All the work you are planning is already been done.
have a look at this way of doing same what you are doinng
string preparedCommand =
#"SELECT TOP 1 [SomeColumn],[SomeColumn2], [SomeColumn3]
FROM [Database].[dbo].[Table]
WHERE [SomeOtherColumn] = #varValue";
[1]: http://www.asp.net/learn/data-access/
More better way of doing the same above is by Using LINQ TO SQL
var result = from someObject in SomeTable
where SomeColumnHasValue == ValueToCompare
select new { SomeColumn, SomeColumn1, SomeColumn2};
No Type Safety Issues
Visualise Database in C# while you
work on it
at compile time less errors
less code
more productive
Following are some of the great resources for LINQ if you are interested
http://msdn.microsoft.com/en-us/vcsharp/aa336746.aspx
http://www.hookedonlinq.com/MainPage.ashx
https://stackoverflow.com/questions/47740/what-are-some-good-linq-resouces
Hope it helps

If you're looking into using just straight ADO.net you might want to go out and find Microsoft's Enterprise Library's Data Access Application Block . David Hayden has a decent article that goes into some detail about using it.
Good luck and hope this helps some.

The easiest way to do data access in C#, to my mind, is using typed DataSets. A lot of it really is drag-and-drop, and it's even easier in .NET 2.0+ than in .NET 1.0/1.1.
Have a look at this article, which talks about using typed DataSets and TableAdapters:
Building a DAL using Strongly Typed TableAdapters and DataTables in VS 2005 and ASP.NET 2.0
A typed DataSet is basically a container for your data. You use a TableAdapter to fill it (which happens with SQL or stored procs, whichever you prefer) and to update the data afterwards. The column names in each DataTables in your DataSet are autogenerated from the SQL used to fill them; and relations between database tables are mirrored by relations between DataTables in the DataSet.

Don't convert data to strings only to try to parse it; DataReaders have methods to convert SQL data to .Net data types:
using (var connection = new SqlConnection(Locale.sqlDataConnection))
using (var command = new SqlCommand(preparedCommand, connection))
using (var reader = command.ExecuteReader())
{
int stringColumnOrdinal = reader.GetOrdinal("SomeColumn");
int dateColumnOrdinal = reader.GetOrdinal("SomeColumn2");
int nullableIntColumnOrdinal = reader.GetOrdinal("SomeColumn3");
while (reader.Read())
{
string var1 = reader.GetString(stringColumnOrdinal);
DateTime var2 = reader.GetDateTime(dateColumnOrdinal);
int? var3 = reader.IsDBNull(nullableIntColumnOrdinal) ? null : (int?)reader.GetInt32(nullableIntColumnOrdinal);
}
}

I test the many different ways for get data from sql server database and i faced & found fastest way is following:
First of all create class with "IDataRecord" parameterized method as per your required properties.
class emp
{
public int empid { get; set; }
public string name { get; set; }
public static emp create(IDataRecord record)
{
return new emp
{
empid = Convert.ToInt32(record["Pk_HotelId"]),
name = record["HotelName"].ToString()
};
}
}
Now create method for get data as below:
public List<S> GetData<S>(string query, Func<IDataRecord, S> selector)
{
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = query;
cmd.Connection.Open();
using (var r = cmd.ExecuteReader())
{
var items = new List<S>();
while (r.Read())
items.Add(selector(r));
return items;
}
}
}
And then call function like:
var data = GetData<emp>("select * from employeeMaster", emp.create);

Related

c#, using dynamic queries

How can I use dynamic queries in C# ? From what I've searched its similiar to when we use SqlCommand with parameters to prevent sql injection(example below).
using (SQLiteConnection DB_CONNECTION = new SQLiteConnection(connectionString))
{
DB_CONNECTION.Open();
string sqlquery = "UPDATE table SET Name =#Name, IsComplete=#IsComplete WHERE Key =#Key;";
int rows = 0;
using (SQLiteCommand command = new SQLiteCommand(sqlquery, DB_CONNECTION))
{
SQLiteParameter[] tableA = { new SQLiteParameter("#Key", todo.Key), new SQLiteParameter("#Name", table.Name), new SQLiteParameter("#IsComplete", table.IsComplete) };
command.Parameters.AddRange(tableA);
rows = command.ExecuteNonQuery();
}
DB_CONNECTION.Close();
return (rows);
}
I'm new to c# and i wondering how can I make this work, thanks in advance.
Basically just build up the string sqlQuery based on a set of conditions and ensure that the appropriate parameters have been set. For example, here is some psuedo-C# (not tested for bugs):
//Set to true, so our queries will always include the check for SomeOtherField.
//In reality, use some check in the C# code that you would want to compose your query.
//Here we set some value we want to compare to.
string someValueToCheck = "Some value to compare";
using (SQLiteConnection DB_CONNECTION = new SQLiteConnection(connectionString))
{
DB_CONNECTION.Open();
string sqlquery = "UPDATE MyTable SET Name =#Name, IsComplete=#IsComplete WHERE Key =#Key";
//Replace this with some real condition that you want to use.
if (!string.IsNullOrWhiteSpace(someValueToCheck))
{
sqlquery += " AND SomeOtherField = #OtherFieldValue"
}
int rows = 0;
using (SQLiteCommand command = new SQLiteCommand(sqlquery, DB_CONNECTION))
{
//Use a list here since we can't add to an array - arrays are immutable.
List<SQLiteParameter> tableAList = {
new SQLiteParameter("#Key", todo.Key),
new SQLiteParameter("#Name", table.Name),
new SQLiteParameter("#IsComplete", table.IsComplete) };
if (!string.IsNullOrWhiteSpace(someValueToCheck)) {
//Replace 'someValueToCheck' with a value for the C# that you want to use as a parameter.
tableAList.Add(new SQLiteParameter("#OtherFieldValue", someValueToCheck));
}
//We convert the list back to an array as it is the expected parameter type.
command.Parameters.AddRange(tableAList.ToArray());
rows = command.ExecuteNonQuery();
}
DB_CONNECTION.Close();
return (rows);
}
In this day and age it would probably be worth looking into LINQ to Entities, as this will help you to compose queries dynamically in your code - for example https://stackoverflow.com/a/5541505/201648.
To setup for an existing database - also known as "Database First" - see the following tutorial:
https://msdn.microsoft.com/en-au/data/jj206878.aspx
You can skip step 1 since you already have a database, or do the whole tutorial first as practice.
Here is some psuedo-C# LINQ code to perform roughly the same update as the previous example:
//The context you have setup for the ERP database.
using (var db = new ERPContext())
{
//db is an Entity Framework database context - see
//https://msdn.microsoft.com/en-au/data/jj206878.aspx
var query = db.MyTable
.Where(c => c.Key == todo.Key);
if (!string.IsNullOrWhiteSpace(someValueToCheck))
{
//This where is used in conjunction to the previous WHERE,
//so it's more or less a WHERE condition1 AND condition2 clause.
query = query.Where(c => c.SomeOtherField == someValueToCheck);
}
//Get the single thing we want to update.
var thingToUpdate = query.First();
//Update the values.
thingToUpdate.Name = table.Name;
thingToUpdate.IsComplete = table.IsComplete;
//We can save the context to apply these results.
db.SaveChanges();
}
There is some setup involved with Entity Framework, but in my experience the syntax is easier to follow and your productivity will increase. Hopefully this gets you on the right track.
LINQ to Entites can also map SQL stored procedures if someone one your team objects to using it for performance reasons:
https://msdn.microsoft.com/en-us/data/gg699321.aspx
OR if you absolutely ust compose custom queries in the C# code this is also permitted in Entity Framework:
https://msdn.microsoft.com/en-us/library/bb738521(v=vs.100).aspx

A very long time of loading data. Large Amount of Data. SQL queries in C#

I have the following code in C# WPF
ConsultaDB consulta = new ConsultaDB();
foreach (var item in lista)
{
var cp = consulta.returnCP(item.Key);
if (cp.Length != 5)
{
//Some code here with the data returned
}
}
list is a collection of >100K elements, and the ConsultaDB object have the following code:
class ConsultaDB
{
string CP;
OleDbConnection conn = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=CCPP.accdb");
public string returnCP(string id)
{
var comm = conn.CreateCommand();
comm.CommandType = CommandType.Text;
comm.CommandText = "SELECT CP FROM CP WHERE ID='" + id+ "'";
var returnValue = comm.ExecuteScalar();
CP = returnValue.ToString();
return CP;
}
public ConsultaDB()
{
conn.Open();
}
}
The problem here is that all that requests to the DB consume a large amount of time to be completed. I saw that the loop is working well, but for sure is not optimized.
So, how can I improve the speed of that process?
Instead of getting the CPs one by one, do a single query, which selects the whole table and then iterate in table. It will greatly improve the speed.
Your query will be:
"SELECT * FROM CP";
Then do something like:
List<string> cps = table_name.AsEnumerable()
.Select(r=> r.Field<string>("...."))
.ToList();
An advice from a guy who has played quite a lot with Access DBs - always use parametrized queries. It will save you most of the incompatible type errors. Especially when you work with dates...
You can try caching the whole CP table in a dictionary:
class ConsultaDB {
private static Dictionary<String, String> s_Data = new
Dictionary<String, String>();
private static void CoreFeedCache() {
using (OleDbConnection conn = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=CCPP.accdb")) {
using (var comm = conn.CreateCommand()) {
comm.CommandText =
#"select ID,
CP
from CP";
using (reader = comm.ExecuteReader()) {
while (reader.Read()) {
s_Data.Add(Convert.ToString(reader[0]), Convert.ToString(reader[1]));
}
}
}
}
}
static {
CoreFeedCache();
}
public static string returnCP(string id) {
String result;
if (!s_Data.TryGetValue(id, out result))
result = null;
return result;
}
}
If CP has about 100K items as well, it will require MegaBytes of RAM.
Get more data at once - since you know list of ids in advance, instead of querying item one by one do one call. If you want items with keys (1,2,3,4) then instead of doing 4 queries just execute one
SELECT CP FROM CP WHERE ID IN (1,2,3,4)
In C# code this would mean
public string returnCP(List<string> ids)
{
var comm = conn.CreateCommand();
comm.CommandType = CommandType.Text;
comm.CommandText = string.Format( "SELECT CP FROM CP WHERE ID IN({0})",string.Join(",",ids));
var returnValue = comm.ExecuteScalar();
CP = returnValue.ToString();
return CP;
}
Page requests if you need a lot of ids. In case you need 10,000 ids it would be inefficient to load all of them at once - it's better to split data requests in several small pieces. So that they still load couple of hundred records but not too much.
If data access is still a bottleneck and you call it frequently for the same objects consider using cache - it will allow you to access data faster. Depending on your architecture in-memory cache can make data access blazingly fast.
This is very case-specific but if CP is not unique (read : it's often the same for many records) you may as well use GROUP query
SELECT CP,COUNT(*) FROM CP GROUP BY CP
In this way you obtain CP values with counts which should reduce amount of data
Please read about SQL Injection to make your code more secure
Modified :
var strId=string.empty;
lista.Foreach(x=>
{
strId+=","+x.itemKey;
});
var cp = consulta.returnCP(strId=strId.TrimStart(','));
So this will pass all the id as comma seperated, to the function and it will executed only once the SQL query and hence the Database connection will be opened only once. The rest of the Logic should be inserted inside a Stored procedure, As the SP is again much faster than that of the normal SQL query. 90% of the time will be saved. Hope this works.

How can I use TableDirect for SQL Server CE?

I have code that works for querying data from a SQL Server CE table and populating a generic list with it. That can be seen here:
But a comment there indicates I should trade in my horse-and-buggy for a Leer Jet; so, I'm trying to adapt code I found here and have this so far:
public static List<HHSUtils.InventoryItem> SelectLocalInventoryItemsTableDirect()
{
var invItems = new List<HHSUtils.InventoryItem>();
using (var conn = new SqlCeConnection(dataSource))
{
conn.Open();
SqlCeCommand cmd = conn.CreateCommand();
cmd.CommandType = CommandType.TableDirect;
cmd.CommandText = "InventoryItems";
using (SqlCeResultSet rs cmd.ExecuteResultSet(ResultSetOptions.Scrollable))
{
cmd.Prepare();
while (rs.Read())
{
var invItem = new HHSUtils.InventoryItem
{
Id = Convert.ToString(rs["Id"]),
PackSize = Convert.ToInt16(rs["PackSize"]),
Description = Convert.ToString(rs["Description"]),
DeptDotSubdept = Convert.ToDouble(rs["DeptDotSubdept"]),
Unit_Cost = Convert.ToDouble(rs["UnitCost"]),
Unit_List = Convert.ToDouble(rs["UnitList"]),
UPC_code = Convert.ToString(rs["UPCCode"]),
UPC_pack_size = Convert.ToInt16(rs["UPCPackSize"]),
CRV_Id = Convert.ToInt32(rs["CRVId"])
};
invItems.Add(invItem);
}
}
}
return invItems;
}
...but since I'm simply looping through the result set to populate the generic list, I reckon I don't want ResultSetOptions.Updatable (and I'll need different code following that). Of the following possibilities:
Insensitive
None
Scrollable
Sensitive
Updatable
...which is best for my situation - Scrollable?
UPDATE
This seems to work fine, and fast, but I still don't know which ResultSetOptions property is optimal...This msdn article talks about this enumeration, but doesn't exactly go into great depth about when they should/not be used.
You'd want to use None in your case. cmd.Prepare is also unnecessary. As indicated in this question, GetValues is also faster.

What is a more efficient way to query MySQL using C#?

Based on links around the StackOverflow site (references below), I've come up with this block of code to perform queries from my C# application to a MySQL database.
using (var dbConn = new MySqlConnection(config.DatabaseConnection))
{
using (var cmd = dbConn.CreateCommand())
{
dbConn.Open();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT version() as Version";
using (IDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
Console.WriteLine("Database Version: " + reader.GetString(reader.GetOrdinal("Version")));
}
}
}
}
The problem I have with this, is that I have to build up this massive block of code every time I have a group of queries to make because I don't (and shouldn't) leave the connection open for the life of the application.
Is there a more efficient way to build the supporting structure (the nested usings, opening the connection, etc), and instead pass my connection string and the query I want to run and get the results back?
Referenced questions:
Use of connections with C# and MySql - Specifically the answer
by tsells
Mysql select where and C#
Update a mysql table using
C#
That is three of the ones I looked at. There were a few more, but my Google-fu can't refind them right now. All of these provide answers for how to perform a single query. I want to perform separate business logic queries - a few of them repeatedly - and don't want to repeat unneeded code.
What I've tried:
Based on the comment from nawfal, I have these two methods:
private MySqlDataReader RunSqlQuery(string query)
{
Dictionary<string, string> queryParms = new Dictionary<string, string>();
MySqlDataReader QueryResult = RunSqlQuery(query, queryParms);
return QueryResult;
}
private MySqlDataReader RunSqlQuery(string query, Dictionary<string, string> queryParms)
{
MySqlDataReader reader = null;
if (queryParms.Count > 0)
{
// Assign parameters
}
try
{
using (var dbConn = new MySqlConnection(config.DatabaseConnection))
{
using (var cmd = dbConn.CreateCommand())
{
dbConn.Open();
cmd.CommandType = CommandType.Text;
cmd.CommandText = query;
using (reader = cmd.ExecuteReader())
{
return reader;
}
}
}
}
catch (MySqlException ex)
{
// Oops.
}
return reader;
}
The problem with this attempt is that the reader closes when it is returned from the method.
Have you considered using an Object Relational Mapper (ORM)? I'm fond of Castle Active Record and NHibernate myself, but there's plenty of others. Entity Framework and Linq to SQL are popular Microsoft solutions too.
With these tools, your queries become pretty simple CRUD method calls that do the connection and session handling for you (mostly).
Instead of creating the reader in a using statement inside your RunSqlQuery method you could return it directly:
return cmd.ExecuteReader();
Then wrap the call to RunSqlQuery in a using statement:
using( var reader = RunSqlQuery(....) )
{
// Do stuff with reader.
}
You could use Actions or Funcs to get what I think you are after.
invoked like this...
RunSqlQuery("SELECT * FROM ...", reader => ReadResult(reader));
private bool ReadResult(MySqlDataReader reader)
{
//Use the reader to read the result
if (!success)
return false;
return true;
}
implemented like this...
private bool RunSqlQuery(string query, Func<MySqlDataReader, bool> readerAction)
{
Dictionary<string, string> queryParms = new Dictionary<string, string>();
return RunSqlQuery(query, readerAction, queryParms);
}
private bool RunSqlQuery(string query, Func<MySqlDataReader, bool> readerAction, Dictionary<string, string> queryParms)
{
MySqlDataReader reader = null;
if (queryParms.Count > 0)
{
// Assign parameters
}
try
{
using (var dbConn = new MySqlConnection(config.DatabaseConnection))
{
using (var cmd = dbConn.CreateCommand())
{
dbConn.Open();
cmd.CommandType = CommandType.Text;
cmd.CommandText = query;
using (reader = cmd.ExecuteReader())
{
return readerAction.Invoke(reader);
}
}
}
}
catch (MySqlException ex)
{
// Oops.
return false;
}
}
Why do you want to return the datareader from the method? It will be closed once u wrap it in inside the using block. Also you can assign parameters only after getting an instance of IDbCommand, so I have moved that part to inside of the using block.
If you strictly want to return the datareader, then better return IEnumerable<IDataRecord> using the yield keyword.
private IEnumerable<IDataRecord> RunSqlQuery(string query,
Dictionary<string, string> queryParms)
{
using (var dbConn = new MySqlConnection(config.DatabaseConnection))
{
using (var cmd = dbConn.CreateCommand())
{
if (queryParms.Count > 0)
{
// Assign parameters
}
cmd.CommandText = query;
cmd.Connection.Open();
using (var reader = cmd.ExecuteReader())
foreach (IDataRecord record in reader as IEnumerable)
yield return record;
}
}
}
Or even better is to read the data there itself and return the data back, as in this question. That way you dont have to rely on classes in db namespaces outside your db class.
I have been down that road. Along the lines of suggesting ORMs, I would recommend EF Code First. Sorry to be a bit off topic, but I have never had a second thought about going back to this pattern after using EF Code First.
Before Code First, EF was quite a pain, but now it has matured and if you had a DB you are potentially modifying structure, i.e. a new app feature requires a new table or column, then EF Code First approach is my recommendation. If it is a third party database or database for another app, that someone else manages its structure, then you only need to refresh your data model whenever they deploy changes, then I would not use Code First, and instead just use traditional EF where you generate/update your model based on some existing database.
Note you could adopt EF and begin using it while you keep your existing code base as-is. This depends on how much of your framework is dependent on using ADO objects though. EF Power Tools extension has a way to generate a Code First model, or you could just use the traditional non-Code First EF to generate a modal from database.
When you want to query, you can get right to the business of what you are trying to query without having alot of infrastructure code or wrappers. The other thing about wrappers like the above, is there are edge cases that you will have to go back to using the ADO API instead of your RunSqlQuery helper.
This is a trivial example, as usually I don't have methods like GetActivePeopleNames, but just put the query where ever it is needed. There is little overhead in terms of fluff code, so it isn't obtrusive to have my query among everything else. Although I do exercise some presenter patterns to abstract the query and data transformation from the business logic.
HREntities db = new HREntities();
private ICollection<string> GetActivePeopleNames()
{
return db.People.Where(p => p.IsActive).Select(p => p.FirstName + " " + p.LastName)
.ToList();
}
I didn't have to create a parameter object. I could have used some variable for Where(p => p.IsActive == someBool) and it would have been safe from SQL injection in that context. The connection is handled automatically. I can use .Include to grab related objects in the same connection if needed.

Retrieve single value from Database, much like DLookup() in MS Access

I am exploring Silverlight (C#) and SQLServer as a next evolution for our current (slow) Access database. So far everything has been great, using DomainServices to retrieve the data I need. In our database we have a table (Supervisors) with Supervisor_ID, Supervisor_FirstName, Supervisor_LastName and many other fields.
What I want to do is recreate a function I use in my current database called EntityNameFirstLast(EntityID) which would take an integer. I could then retrieve the value of [Supervisor_FirstName] from [Supervisors] table where [Supervisor_ID] == EntityID using the following:
FirstName = DLookup("[Supervisor_FirstName]", "Supervisors", "[Supervisor_ID] = EntityID
I would do the same for lastname and combine the strings returning one string with First and last name.
How can I get just a single value from my database through my DomainService (or any way for that matter)? I understand that IQueryable GetSupervisorByID(Int SupID) will return the entire row that I need, but how can I get a specific field from that row?
I am also aware that I can set the DomainDataSource in my XAML and then bind to the data I want, but I am curious if what I asked above is doable or not.
There are number of ways you can accomplish your requirement if what you need is a single value from MS-SQL server:
1.Use a Query to do the concatenation and then use its output in your code
Select Supervisor_FirstName + ' ' + Supervisor_LastName as Supervisor_FullName From Supervisors Where Supervisor_ID = EntityID
Now you can get the above query to execute through a SqlCommand and get the part thats interesting to you
private string GetSupervisorFullName(string entityID, string connectionString) {
string query = "Select Supervisor_FirstName + ' ' + Supervisor_LastName as Supervisor_FullName From Supervisors Where Supervisor_ID = #EntityID";
string supervisorFullname = "";
using(SqlConnection con = new SqlConnection(connectionString)) {
SqlCommand cmdSupervisorFullname = new SqlCommand();
cmdSupervisorFullname.Connection = con;
cmdSupervisorFullname.CommandText = query;
cmdSupervisorFullname.CommandType = CommandType.Text;
SqlParameter paraEntityID = new SqlParameter();
paraEntityID.ParameterName = "#EntityID";
paraEntityID.SqlDbType = SqlDbType.NVarChar;
paraEntityID.Direction = ParameterDirection.Input;
paraEntityID.Value = entityID;
cmdSupervisorFullname.Parameters.Add(paraEntityID);
try {
con.Open();
supervisorFullname = (String) cmdSupervisorFullname.ExecuteScalar();
} catch(Exception ex) {
Console.WriteLine(ex.Message);
}
return supervisorFullname;
}
}
2.Second way would be create a Scalar function in the SQL for your requirement and then access that function using the same kind of method as mentioned above.
Then finally you would take the return value from your method GetSupervisorFullName and populate any control value of your choice.
Please do note that there are again other methods of doing the same with LINQtoSQL or with any other ORM tools. The above 2 methods are the basic way of accomplishing them.
Hope that helps.

Categories

Resources