Connect Azure MI SQL View to MVC app as read only code first - asp.net-mvc

One aspect of an ASP.net core (6) MVC app I am working on needs to query an SQL View that already resides in an Azure SQL MI.
I need to be able to query this SQL View to be able to retrieve the data based on user input but with the following conditions.
I cannot use Entity Framework.
The connection has to be read only.
This has to be database first.
As of yet I do not have access to this View or any of the tables it draws from. However I am expected to have code ready to plug a connection string into.
Unfortunately any resources I have been able to find don't seem to apply to my specific conditions. So any advice in what direction or approach would work best would be appreciated.

Those are by no means "silly" conditions. You didn't specify the language or the database but I'll make assumptions
I cannot use Entity Framework
Just use standard ado.net
https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/ado-net-code-examples#sqlclient
(I know that Link only answers are frowned upon)
The connection has to be read only.
Ensure that the account you connect under is read only. In SQL Server this is achieved by making you a member of the db_datareader group. This is something that should be enforced by the DBA that gives you an account
This has to be database first.
That's not really relevant. Just use the linked sample code to read from the existing view.
Literal copy paste of code at the link above:
using System;
using System.Data;
using System.Data.SqlClient;
class Program
{
static void Main()
{
string connectionString =
"Data Source=(local);Initial Catalog=Northwind;"
+ "Integrated Security=true";
// Provide the query string with a parameter placeholder.
string queryString =
"SELECT ProductID, UnitPrice, ProductName from dbo.products "
+ "WHERE UnitPrice > #pricePoint "
+ "ORDER BY UnitPrice DESC;";
// Specify the parameter value.
int paramValue = 5;
// Create and open the connection in a using block. This
// ensures that all resources will be closed and disposed
// when the code exits.
using (SqlConnection connection =
new SqlConnection(connectionString))
{
// Create the Command and Parameter objects.
SqlCommand command = new SqlCommand(queryString, connection);
command.Parameters.AddWithValue("#pricePoint", paramValue);
// Open the connection in a try/catch block.
// Create and execute the DataReader, writing the result
// set to the console window.
try
{
connection.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Console.WriteLine("\t{0}\t{1}\t{2}",
reader[0], reader[1], reader[2]);
}
reader.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
}

Related

Web API in ASP.net C#

I want to create a web API controller that returns product details with id. Using stored procedure calls from a database class, not DB context. Sending Request with ID & getting a response with Jason's values.
I saw many examples but they are directly using stored procedures from the DB context. But I want to introduce a connection string & call that method in business class than a business class call to the controller with the response return.
Please help with a small example
Here is one example. You can choose between using SQL Command or SQL Adapter, try searching a little bit more about it.
Programming isn't only writing a code it's also googling for solutions.
// Setup connection string to access local SQL Server 2000
string connectionString = "server=localhost;" +
"database=Northwind;uid=sa;pwd=manager";
// Instantiate the connection, passing the
// connection string into the constructor
SqlConnection con = new SqlConnection(connectionString);
// Open the connection
con.Open();
// Create and execute the query
SqlCommand cmd = new SqlCommand("SELECT * FROM Customers",con);
SqlDataReader reader = cmd.ExecuteReader();
// Iterate through the DataReader and display row
while(reader.Read()) {
Console.WriteLine("{0} - {1}",
reader.GetString(0), reader.GetString(1));
}
Source

Create Query without entity framework

I have the following code, but I can’t work out what I need to put in place of the // before .AddObject(Model); and .SaveChanges(); to get the method to work. It’s a create query but I’ve only ever done this while using the Entity Framework before now, in this case I’m not using EF.
[HttpPost]
public ActionResult Registration(UserDetailModel Model)
{
if (ModelState.IsValid)
{
Model.UserNameFK = User.Identity.Name;
Model.CompanyName = "CompanyName";
Model.IEMI = "IEMI";
//.AddObject(Model);
//.SaveChanges();
return RedirectToAction("Registration", "Home");
}
return View(Model);
}
Am I close?
Cheers,
Mike.
I hope you know Entity Framework is an Object Relational Mapping framework for .NET.
Basically it creates entity classes that map up to your database and make it easy to perform Create/Read/Update/Delete operations without writing any SQL.
If you're not using Entity Framework, you could use another ORM like NHinbernate.
OR
You could use plain ADO.NET classes with SQL to write/read data to/from your database.
Ex: If you're using SQL Server you would use the System.Data.SqlClient namespace for writing to your SQL DB, see the SQLCommand class (Writing to other supported DB's work the same way)
You would do something like this with the function below it:
CreateCommand(//just as an example you can use values from your model in sql
"INSERT INTO Users(Name, CompnayName, IMEI,) VALUES ("
+ Model.UserNameFK +", val2, val3,...)",
"your connection string"
);
private static void CreateCommand(string queryString,
string connectionString)
{
using (SqlConnection connection = new SqlConnection(
connectionString))
{
SqlCommand command = new SqlCommand(queryString, connection);
command.Connection.Open();
command.ExecuteNonQuery();
}
}
See this for more documentation.

How to check whether username already exists using ajax in asp.net?

I am working on an application which has a registration form and I have to display to the user whether the username exists or not.
I am using asp.net mvc3 and planned to use AJAX to achieve this.
I have a form
<tr>
<td>User Name*</td>
<td><input id="UserName" name="UserName" type="text" onblur="check(this.value);"/></td>
<td id= "UName"></td>
</tr>
which calls a .js file that has the folling contents
function check(User) {
...
var url = "/UserNameCheck/Index";
url += "?User=" + User;
xmlHttp.onreadystatechange = state_Change;
xmlHttp.open("GET", url, true);
xmlHttp.send(null);
}
function state_Change() {
if (xmlhttp.readyState == 4) {// 4 = "Response loaded"
if (xmlhttp.status == 200) {// 200 = Response Error Free
document.getElementById("UName").innerHTML = xmlHttp.responseText
}
else {
alert("Problem retrieving XML data");
}
}
}
I alerted the username and I am getting the correct value that i had entered. Now, the URL is /UserNameCheck/Index where UserNameCheck is a controller and Index is a method in that.
The controller has this code.
public ActionResult Index(string User)
{
string UserName;
try
{
Response.Cache.SetCacheability(HttpCacheability.NoCache);
UserName = Request.QueryString["User"];
ConnectionPackage.ConnectionClass cc = new ConnectionPackage.ConnectionClass();
conn = cc.con;
string sql = "Select UserName FROM UserDetails where UserName = '" + UserName + "'";
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.CommandType = CommandType.Text;
object p = cmd.ExecuteScalar();
cmd.ExecuteNonQuery();
string u = (string)p;
if (u.Length==0 || u.Equals("NULL") || u.Equals("null")||u.Equals("Null"))
{
return View();
}
return null;
}
catch (Exception ex){
}
and the view has
String buffer = " <table><tr><td id = 'UName' >" This user name already exists. Please select some other unser name.
buffer = buffer + "</td></tr></table>";
response.getWriter().println(buffer);
I also tried writing
Response.Clear();
Response.Write("UserName already exists. Please select another UserName");
Response.End();
instead of returning View.
But in both the cases, I didn't get any message that the username exists even though I typed a user name that was already present in the database.
The connection string work for inserting into the database, so I dont think there is a problem with that. Is there a problem with the URL that I have mentioned in the js file? Or is my entire approach wrong?
I am basically from java background so dont know much about asp.net. Please do help.
Thank you very much in advance.
I followed what was given in MSDN article How to: Implement Remote Validation in ASP.NET MVC
jQuery in Action is the most popular jQuery book
You're doing alright but you could make this a whole lot easier on yourself. If you are usinng MVC3 with Razor, your app already has jQuery installed.
Use the $.ajax() method to perform the calls to your controller action that checks names...
Bind the $.ajax() call "unobtrusively" which means instead of on your HTML control, bind the event to your control from the jquery/javascript.
Second, if you want a little fancy performance, you can bind it via the live() jquery function or keyup event, so that as you are typing the ajax call is made and you find out realtime.
Ultimately you will end up with a lot less javascript, and your JS stuff will be cleanly separated from your markup.
As far as your controller action is going, it looks fine for playing around and learning, but you'd want to think about either (a) putting your SQL statement as a stored procedure on the db server and calling that, or (b) writing a repository pattern class and then using LINQ to do your query work after the DB fetch.
Another possibility would be to use Entity Framework 4.1 via NuGet to eliminate both needs. It can have a bit of a learning curve, but there's lots of good stuff out there and your example would be fairly simple to get started with.
Let me know if you have any specific concerns with your code and I can provide a more detailed answer.

Query with ROWID via data provider

I am looking to query a table like the following sql:
select * from itd093 where rowid='Cumn99AAAAMzAAAAAJ'
It could find a unique record in the ADS architect client. However, when this query was sent from the code level through the .NET data provider, it return none result from the database server.
Does anyone have ideas on how I can make the sql above return the result through the .NET data provider?
Some sample code here:
public void DataProviderTest()
{
using (AdsConnection conn = new AdsConnection(#"Data Source=D:\Development\FDDB;ServerType=ADS_LOCAL_SERVER;TableType=ADS_CDX;TrimTrailingSpaces=TRUE;"))
{
conn.Open();
AdsCommand cmd = new AdsCommand("select * from itd093 where rowid='Cumn99AAAAMzAAAAAJ'", conn);
AdsDataReader reader = cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
if (!reader.Read())
throw new Exception("no records");
}
}
Thanks Mark for pointing out that the .NET data provider and the Advantage Data Architect should return the same result.
The problem to be the different connection strings. From the help documentation, it says,the first six characters of the ROWID represent the database ID. It is based on the connection path.
I was mistakenly copy a rowid from the data architect to test with data provider, and the connection strings are different. That's why I couldn't get a result returned from the data provider as it does from the data architect.

Repository Connection Pooling

I'm in a hoo-ha with my boss as I can't shift to using newer technologies until I have proof of some outstanding issues. One of the main concerns is how repositories deal with connections. One of the supposedly largest overheads is connecting and disconnecting to/from the database. If I have a repository where I do the following:
public ContractsControlRepository()
: base(ConfigurationManager.ConnectionStrings["AccountsConnectionString"].ToString()) { }
with the class like so:
public class ContractsControlRepository : DataContext, IContractsControlRepository
with functions like:
public IEnumerable<COContractCostCentre> ListContractCostCentres(int contractID)
{
string query = "SELECT C.ContractID, C.CCCode, MAC.CostCentre, C.Percentage FROM tblCC_Contract_CC C JOIN tblMA_CostCentre MAC ON MAC.CCCode = C.CCCode WHERE C.ContractID = {0}";
return this.ExecuteQuery<COContractCostCentre>(query, contractID);
}
Now if in my controller action called _contractsControlRepository.ListContractCostCentres(2) followed immediately by another call to the repository, does it use the same connection? When does the connection open in the controller? When is it closed?
Cheers
EDIT
I'm using hand-written LINQ as suggested by Steve Sanderson in his ASP.NET MVC book.
EDIT EDIT
To clarify, I'm using LINQ as my ORM, but I'm using raw SQL queries (as shown in the extract above) for querying. For example, here's a controller action:
public ActionResult EditBusiness(string id)
{
Business business = _contractsControlRepository.FetchBusinessByID(id);
return View(business);
}
I'm not opening/closing connections.
Here's a larger, more complete extract of my repo:
public class ContractsControlRepository : DataContext, IContractsControlRepository
{
public ContractsControlRepository()
: base(ConfigurationManager.ConnectionStrings["AccountsConnectionString"].ToString()) { }
public IEnumerable<COContractCostCentre> ListContractCostCentres(int contractID)
{
string query = "SELECT C.ContractID, C.CCCode, MAC.CostCentre, C.Percentage FROM tblCC_Contract_CC C JOIN tblMA_CostCentre MAC ON MAC.CCCode = C.CCCode WHERE C.ContractID = {0}";
return this.ExecuteQuery<COContractCostCentre>(query, contractID);
}
Then ContractsControlRepository is instantiated in my controller and used like _contractsControlRepository.ListContractCostCentres(2). Connections aren't opened manually, DataContext deals with that for me.
Without knowing the details of your ORM and how it connects the SQL database drivers will connection pool. When a connection is closed it is released back to the pool and kept open for X number of seconds (where X is configurable). If another connection is opened and all the parameters match (the server name, the application name, the database name, the authentication details etc.) then any free, but open connections in the pool will get reused instead of opening a brand new connection.
Having not read the book in question I don't know what "manual linq" actually is. If it's manual means you're getting the tables back youself then obviously you're doing the connection open/close. Linq to SQL will use a new connection object when a statement is finally executed at which point connection pooling comes into play - which means a new connection object may not be an actual new connection.

Resources