SQL and C# retrieving a single record from database - c#

I have a webpage built with a dropdown that has a list of books. These books are stored on the sql sever. Using the MVC and aspx pages i am trying to figure out how to retrieve information about about a book such that when the user selects a book it passes the price of the book. I am new to sql sever and var statements.
I am able to retrieve the books name from the webpage and send it to my controller
In my model i am trying to get that data here is my thought. I want to get the price and store into a string. But the only way i have seen to pull information is using the var statement.
such that
var price = from p in BooksDB.Price
where p.Book_Name==bookName
select new {p.Book_Price}
but how do i get that value and store it into a string based on the Books_Name that I have retrieved from the dropdown box
by the way my table looks like this
Id_Num Book_Name Book_Price
1 Pro C# 29.99
2 Beg C++ 10.99

First a terminology correction.
var is just a keyword the compiler lets you use to subsitute for the type. During compiletime, the compiler will figure out what the type is based on usage.
var myString = "hihihi";
string myString = "hihihi";
The var statement has nothing to do with accessing a database, although it was added to make using LINQ easier on us lazy developers.
Instead what you are doing is creating a LINQ to SQL query. I've modified it slightly (you don't need to create an anonymous object). After you create the statement, you need to execute it by calling "ToList(), First(), or FirstOrDefault() etc"
LINQ typically employs lazy or deferred evaluation for queries, and isn't executed until you trigger execution.
var price = from p in BooksDB.Price
where p.Book_Name==bookName
select p.Book_Price;
//assuming Book_Price is stored as a string datatype.
string bookPrice = price.FirstOrDefault();
//otherwise
string bookPrice = (price.FirstOrDefault() ?? "").ToString();
if(!String.IsNullOrEmpty(bookPrice))
{
//do something with the string.
}

If I understand correctly something like below should work.
var record = BooksDB.Price.FirstOrDefault(r => r.Book_Name == bookName);
If record is not null at this point then record.Book_Price should contain the data you are looking for (not accounting for ambiguity in the database.)

Instead of select new {p.Book_Price}, use something like select p.Book_Price. You could add .ToString() to the end to force it to come out as a String rather than the data type from the table.
You'll also want to wrap the entire LINQ statement in () and append .FirstOrDefault() to get just one value. The "OrDefault" part protects you from an exception when the result set us empty.

Related

Union IQueryable and List

This is my code:
var query = context.SomeEntities.Select(e => new SomeDto
{
Name = e.Title,
})
The variable query is IQueryable.
var list = new List<SomeDto>
{
new SomeDto
{
Name = "SomeName1"
},
new SomeDto
{
Name = "SomeName2"
}
};
Now I need union these collections,I write
query = query.Union(list)
But in this place I get exception
Unable to create a constant value of type 'SomeDto'. Only primitive types or enumeration types are supported in this context
I know that I can do ToList() for first collection,but I need union collections without call to database.How can I do this?
As user3825493 pointed, there are answers regarding similar issues. The first link pretty much explains the whole thing.
Your problem is that due to the fact that Union is mapped to SQL UNION, arguments of the operation are to be converted to data types acceptable by Entity Framework. However, the only types acceptable by it for items inside IEnumerable input parameters are, as specified in the error you get, primitive types and enum's.
You should either:
var unionOfQueryWithList = query.AsEnumerable().Union(list)
or, if you like to use the SQL facilities, write a stored procedure which performs the union as part of its logic and find the way to pass your data into SQL, such as this.
The former loads all the results of the query into a memory before performing the union. It is convenient for the cases when you have all the pre-filtered data returned from EF and only want to use the output for later processing in your code.
The later takes you out of the EF zone and required for the cases when you have operations which will benefit from running on SQL engine, such as filtering or joining DB data based on a complex data you have access to in your code.
either you convert the query to IEnumerable or you can try this :
list.Union(query); // use Union() of list not query :)
it will work and you still don't need to get data from DB you can reverse the order if you want :)

Convert SQL query to LINQ query but only select specific values to return

I have myself a SQL query
SELECT follow_up_date, MAX(last_contact_date) AS last_contact_date
FROM db_accounts_last_contacts p
GROUP BY p.account_id
I have tried
var queryTest = context.db_accounts_last_contacts.SqlQuery(#"SELECT follow_up_date, MAX(last_contact_date) AS last_contact_date
FROM db_accounts_last_contacts p
GROUP BY p.account_id");
but I get this error.
The data reader is incompatible with the specified 'dbModel.db_accounts_last_contacts'. A member of the type, 'id', does not have a corresponding column in the data reader with the same name.
I don't want to pull out all of the information as this table maybe updated later down the line, I would just like to pull out these two columns
I think you are trying to access the DB table withing the table itself.
and you are missing the "AS" before the p variable.
Try the following :
var queryTest = context.ExecuteSqlCommand(#"SELECT follow_up_date, MAX(last_contact_date) AS ast_contact_date
FROM db_accounts_last_contacts AS p
GROUP BY p.account_id, follow_up_date, ast_contact_date ");
let me know how it goes.
P.S.
I really recommend using EntityFramework as it converts your viewing point from an SQL'ish one into a C# pov. which is usually easier to understand.

Pass in a field name at run time using Dynamic LINQ library?

This is a small application used on a company intranet by 4 people at the most, and I am new to C# and .NET, so the solution does not have to be grandiose.
I am trying to create a search field for simple .NET C.R.U.D app where the user can pick a category they wish to search from (such as Application Name, or Manager) and then a text-box where they can filter the results based on that field name. The items in the drop down menu are the class field members and I would like for all of them to be searchable. I'm using the Dynamic Linq Library to create a string so that I can pass the column name at run-time but for some reason my queries return no results.
Here is my current query
dr_details = dr_details.Where("#0 == #1",searchType, searchString);
So for instance, searchType & searchString get their values from the query string (We'll say "Manager" and "Joe", respectively) so that the query should be substituted as:
dr_details = dr_details.Where("Manager == Joe");
this gives me no results. However if I hard code the string "Manager == Joe" into the query runs fine.
Any suggestions? This problem would make me yank out my hair if it was long enough! :p
You don't necessarily have to use dynamic linq for this if you don't want.
Try something like this:
var query = myList.AsQueryable();
switch(searchType)
{
case "Manger":
query = query.where(x=> x.Manager == searchString);
break;
case "....":
break;
default:
// No search type match in string... an exception? your call
break;
}
I find this more intuitive since it "builds" the query as it goes...
Edit:
If that is too painful try following this post

How to hide some fields using NHIbernate ICriteria?

Here's a scenario that I am working on : Right now we have a SQL statement that reads like this :
SELECT a.ID,a.MsgNumber,CASE WHEN #HasAccess=1 THEN Title ELSE '*********' END AS Title FROM Messages
We want that operators be able to see if a message registered in system but can't see the title if they are not authorized.
I'm changing this part of code so we can use a NHibernate criteria to generate the same result (so we can produce dynamic queries according to filters that user selects).
I know that I can use projections to get some fields or constant values from a criteria but can not figure out how I should combine them to do what I want.
It looks like #HasAccess is a parameter passed in by your code, not a value determined by the database. If so, then the easiest way to do what you want is to modify the criteria in code based on the value that you would pass through in the query, eg:
var projections = Projections.ProjectionList()
.Add(Projections.Id())
.Add(Projections.Property("MsgNumber"))
.Add(hasAccess ? Projections.Property("Title") : Projections.Constant("*********"));
var criteria = session.CreateCriteria<Message>()
.Add(... your restrictions ...)
.SetProjection(projections)
.List<object[]>();
If however #HasAccess is determined by your database somehow, then you could use:
Projections.Conditional(Restrictions.Eq("HasAccess", 1),
Projections.Property("Title"),
Projections.Constant("*********"))
assuming that you can get HasAccess into your criteria somehow

Dynamically Modifying a LINQ to SQL Select Statement's Columns

I'm trying to build a REST-ful API for my app. Currently I have something like this:
www.example.com/submissions/?format=json
This will return latest ten submissions in JSON. Each object has its details, such as submission name, date created, user, body, etc.
I'd like to do something such as:
www.example.com/submissions/?format=json&filter=name,user
The filter should make the request to return the same result but to only include the details mentioned, i.e. each object will only have a name and user.
This is fairly straightforward in terms of the JSON output. I can load all the columns from the database and create and serialize an object that will only include the columns in the filter. However, I do not want to load all the columns in the database - I want to bother my database with only the columns that I will include in the response.
I want to do something like this:
var result = from record in Submissions
select
{
Name,
Date,
User,
Body
};
Now I have the result object, which is IQueryable, so no call to database made yet.
Then, I should examine the filter querystring and exclude the columns that are not mentioned.
Finally, I can execute the select statement with something like
JavaScript.Serialize(result.ToList());
Is this possible with LINQ to SQL?
An alternative to building your Select expression tree by hand is Dynamic LINQ, which provides a Select method that takes a string:
var filter = "name,user";
var result = Submissions.Select("new(" + filter + ")");
The string is then translated into an expression tree and passed on to your query provider.
Yes. You are going to want to research Modifying Expression Trees. Specifically the MemberInit Expression.

Categories