Dynamic Object - Tidy property names? - c#

I'm using some code to execute a SQL and return a IEnumerable of dynamic objects. The code is here if you want to see it.
I have a table with a column name such as APPLICATION_NAME;
In my object I have to reference it like so:
var results = ReturnResults("Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=rawdb;Data Source=mypc", "SELECT * FROM APPLICATIONS");
string name = results.First().APPLICATION_NAME;
Is there a way to make property names resolve to something tidier? ie.
string name = results.First().ApplicationName;
Thanks

There are some ToCamelCase() extensions out there (just google it). But if you would implement it into your dynamic object. How do you know which shiny name you have to take for an ugly column name?
Instead you should rewrite your select statement to return nice names, instead of implementing some algorithm into the dynamic object. How about this statement:
SELECT APPLICATION_NAME as 'ApplicationName' FROM APPLICATIONS
So it is clear to everyone who reads the sql statement how to access the columns through the dynamic object.

Related

How to generate nHibernate raw sql for Insert/Update without execution?

Is it possible to generate a raw SQL statement for insert/update operations using nHibernate without actually executing them? Assuming of course that everything (mappings, connectionStrings, etc.) is properly configured?
The closest thing I've found is to call:
Session.SessionFactory.GetClassMetadata(typeof(Client))
Which returns an object of type SingleTableEntityPersister containing SQLIdentityInsertString, that looks like this:
INSERT INTO Client (FirstName, LastName) values (?, ?)
But it would still require me to bind all of the properties manually, and on top of that SQLIdentityInsertString is a protected property. Are there any proper ways of doing that?
Okay, the closest thing I've found is to construct your own sql query with a string builder. First you need to extract your class metadata:
var metaData = Session.SessionFactory.GetClassMetadata(typeof(Client)) as SingleTableEntityPersister;
Then you can retrieve other information, such as:
var propertyNames = metaData.PropertyNames;
var tableName = metaData.TableName;
var firstPropertyValue = metaData.GetPropertyValue(client, propertyNames[0], EntityMode.Poco);
Once you have that information you can construct your own query manually. Not exactly the solution I wanted, but it's as close as it gets, I think.
However, one thing to note is that Session.CreateSQLQuery(string) method is currently bugged, and as a result SetParameter method doesn't work with more than 10 named parameters. There already seems to be a bug report created for this on NHbiernate's Jira.

Filling sqlCommand Parameters with an object - Potential Issues

I have written a method does the following.
What it does
Parses an SqlCommand object string for parameters in a parameterized SQL query.
Excludes any parameters declared and parameters starting with ##.
Finds properties in an object using reflection that share the parameter name
Uses the object's property value and adds a parameter to the
parameter collection
Reflection
This method is designed to be used in a web environment that is highly customizable and get parameters from a variety or deserialized JSON objects. I am very aware that reflection is slow but the idea is only to reflect a single object for a return set and not to be used in data processing loops, the reflection issue is not something I care about.
Questions
Aside from listing downsides of reflection, I would like to know what issues anyone sees with this code that I might not have considered. Please make the assumption that the object has the correct properties. I am having a hard time testing this because I wrote it to parse the SQL that I know. I cannot write tests for SQL I don't know. It seems to pass every test of SQL I have written.
Is there any issue with the code
Are there potential queries that would break this?
Can the code be written more efficiently ?
Are there any other issues that you might see with this idea ?
Code
public static void LoadParametersByObject(SqlCommand command, Object obj)
{
var DeclareREG = new Regex("(?<=Declare\\s*)#\\w{1,}");// finds all Declare #name
var ParameterREG = new Regex("(#{1,2}\\w{1,})");//finds all #name and all ##name
List<String> Exclude = (from Match x in DeclareREG.Matches(command.CommandText) select x.Value.Replace("#", "").ToUpper()).ToList();
List<String> Include = (from Match x in ParameterREG.Matches(command.CommandText)
where !x.Value.StartsWith("##") && !Exclude.Contains(x.Value.Replace("#", "").ToUpper())
select x.Value.Replace("#", "").ToUpper()).Distinct().ToList();
foreach (PropertyInfo prop in (from x in obj.GetType().GetProperties() where Include.Contains(x.Name.ToUpper()) select x).ToArray())
{
command.Parameters.AddWithValue("#" + prop.Name, prop.GetValue(obj));
}
}
Code Breakdown
Use regex to find Declare(whitespace)#parameter and put it in the
exclude list
Use regex to find any parameters starting with # or ##.
throw out the ## as they are internal SQL objects and check the #
parameters to make sure they are not in the exclude list as they
were declared in the text of the query and add the results to the
include list
Iterate the include list and search for the object property with the
same name
Add the property value to the SqlCommand's SqlParameter collection
Thanks in advance for your help

Returning from a field collection with Dynamic library

we are developing a framework that through the one url, generate a query based on the mapped entities by entity framework.
We are using the Dynamic Library ( http://lcs3.syr.edu/faculty/fawcett/handouts/CoreTechnologies/CSharp/samples/CSharpSamples/LinqSamples/DynamicQuery/Dynamic%20Expressions.html) and we are struggling to return to the fields of a relationship 1..N.
Example:
TB_PEOPLE > TB_PHONE
Based on this relationship, I need to accomplish the same idea of ​​following linq:
var sql = from p in context.SomeTable
select new {
NAME = p.NAME,
PHONES = p.TB_PHONE.Select(ph => ph.PHONE)
};
Since I'm not working with typing, we chose to use dynamic library because apparently allowed us the flexibility to manipulate strings to return.
Then following the same idea , we set up the following line:
var sql = context.SomeTable.Select("new (TB_PEOPLE.TB_PHONE.PHONE)");
In this case , the returns an error stating that the attribute "PHONE" does not exist "TB_PEOPLE" of course ! So much so that we try to say that this attribute belongs to the table "TB_PHONE" but he does not understand.
So I ask you, how do I return to only certain fields of an entity where the relationship can be N? Also tried to call the method "Select":
var sql = context.SomeTable.Select("new (TB_PEOPLE.TB_PHONE.Select(PHONE))");
...there but I am informed that this method can not be used.
I do not know what else to do, any help will be appreciated!
Thank you.

SQL and C# retrieving a single record from database

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.

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