before in application , i used a function . i add it to my sqlserver --> database --> Programmabality ---> Function ---> Scalered-Value Function
and in the application i used , like this :
dbo.MyFunc(_txt.text);
but now i need this function in my project . its mvc4 web site .
is it possible to use like that ? and where i should add this function?
of course i did like application , but db.MyFunc() dose not recognize in my class.
so,my project is CodeFirst .
As you are using code first DB approach, code changes will be reflected in SQL server DB. So you'll have to implement it in C#
Below is one example. Got from How to: Create and Run a CLR SQL Server User-Defined Function
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
public partial class UserDefinedFunctions
{
public const double SALES_TAX = .086;
[SqlFunction()]
public static SqlDouble addTax(SqlDouble originalAmount)
{
SqlDouble taxAmount = originalAmount * SALES_TAX;
return originalAmount + taxAmount;
}
}
If you just want direct access to this specific function:
public Object MyFunc(String txt_text)
{
Object result = null;
String connectionstring = "DataSource=.\SQLEXPRESS;"
+ "Initial Catalog=DEMO;"
+ "Integrated Security=True"; // or whatever you use....
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand("SELECT dbo.Myfunc(#p1)", connection))
{
command.CommandType = CommandType.Text;
command.Parameters.AddWithValue("#p1", txt_text);
result = command.ExecuteScalar();
}
}
return result;
}
That would establish a connection to the database and execute that scalar-values function, then place the result within result. This takes any other database infrastructure out of the equation and just allows you to directly call your SQL function.
Related
Company asked me to implement ASP.NET Zero web portal for our solutions. ASP.NET Zero based on ASP.NET Core + Angular Js. I am learning it since last 15 days. Now I wanted to know how to call stored procedures from ASP.NET Core and serve it in Angular.
Can Anyone explain with simple example?
You have several options to choose in order to call a SP from your Application Services regardless of SPA or MPA solution.
You can use Abp.Dapper nugget package
You can create a method in your EF DbContext which let you call any stored procedure.
Create a Repository class for your desired entity on Entity Framework part. It should inherit from RepositoryBase class and implement interface for related entity. Then add a method for calling a stored procedure.
For example:
public class UserProfileRepository : CommEngineRepositoryBase<UserProfile, int>, IUserProfileRepository
{
public UserProfileRepository(IDbContextProvider<CommEngineDbContext> dbContextProvider, IActiveTransactionProvider transactionProvider)
: base(dbContextProvider, transactionProvider)
{
}
public async Task<List<(string, int)>> GetCategoryAnalyticsForUser(int tenantId, DateTime startDate, DateTime endDate, long? userId)
{
EnsureConnectionOpen();
var nullableUserId = userId.HasValue ? (object)userId : DBNull.Value;
var output = new List<(string, int)>();
try
{
using (var command = CreateCommand("GetCategoryAnalyticsForUser",
CommandType.StoredProcedure,
new SqlParameter[]
{
new SqlParameter("#TenantId", tenantId),
new SqlParameter("#UserId", nullableUserId),
new SqlParameter("#StartDate", startDate),
new SqlParameter("#EndDate", endDate)
}
))
{
using (var dataReader = await command.ExecuteReaderAsync())
{
while (dataReader.Read())
{
string tag = dataReader["Tag"].ToString();
int.TryParse(dataReader["Count"].ToString(), out int count);
output.Add((tag, count));
}
}
}
return output;
}
catch (Exception ex)
{
throw new UserFriendlyException(ex.Message, ex.ToString());
}
finally
{
CloseDbConnection();
}
}
}
You call this from IUserProfileRepository interface.
Enjoy!
i wonder how to implement M-V-C ADO without using EF.
just like a pure ADO implementation. any suggestions and sample are appreciated Thanks guys.
Basic ADO.NET connections haven't really changed at all with MVC coming around. They still rely on things like SqlConnection objects and their associated commands.
If you wanted to build a simply query, it might look like the following :
// Build your connection
using(var connection = new SqlConnection("{your-connection-string-here"}))
{
// Build your query
var query = "SELECT * FROM YourTable WHERE foo = #bar";
// Create a command to execute your query
using(var command = new SqlCommand(query,connection))
{
// Open the connection
connection.Open();
// Add any parameters if necessary
command.Parameters.AddWithValue("#bar", 42);
// Execute your query here (in this case using a data reader)
using(var reader = command.ExecuteReader())
{
// Iterate through your results
while(reader.Read())
{
// The current reader object will contain each row here, so you
// can access the values as expected
}
}
}
}
You can use the type of ADO commands and paramaterized SQL seen here to retrieve data:
conn.Open();
cmd.CommandText = "SELECT id, desc FROM mytable WHERE id = #id";
cmd.Parameters.AddWithValue("#id", myid);
using (var reader = cmd.ExecuteReader())
{
if (!reader.Read())
{
return null;
}
return new myItem
{
Id = reader.GetInt32(reader.GetOrdinal("id")),
Desc = reader.GetString(reader.GetOrdinal("desc")),
}
}
There are lot of examples on MSDN for CRUD.
I am trying to create a "generic" method in a data access layer that executes a passed stored procedure in Sql Server and also takes a list / array / collection of SqlParameters, to make the usage of a stored procedure call within other parts of the code easier (without requirement to care for connection, command objects etc).
The goal is sth. like this:
int iAffectedRows = dal.RunProcedure("dbo.mySP", parameters);
The parameters should of course be defined previously but without the types. I want them to be created using the AddwithValue() method of SqlParameterCollection class.
It looks like it's impossible because the SqlParameterCollection class can't be instanciated. Look at this discussion.
Anyone knows how to create this?
It's not a good idea to send in a DbParameterCollection (SqlParameterCollection), since it's tightly coupled (which you have discovered) with the ADO.NET infrastructure that you're trying to abstract away. It's better to map your own parameter representation to the collection inside your method.
You can solve it using something like this:
public class DataAccess
{
private ConnectionStringSettings _settings;
public DataAccess(ConnectionStringSettings settings)
{
_settings = settings;
}
public int RunProcedure(string name, dynamic parameters)
{
using (var conn = CreateConnection())
using (var command = CreateCommand(conn, name, parameters))
{
return command.ExecuteNonQuery();
}
}
private DbConnection CreateConnection()
{
var factory = DbProviderFactories.GetFactory(_settings.ProviderName);
var connection = factory.CreateConnection();
connection.ConnectionString = _settings.ConnectionString;
connection.Open();
return connection;
}
private DbCommand CreateCommand(DbConnection conn, string commandText,
object parameters)
{
var cmd = conn.CreateCommand();
cmd.CommandText = commandText;
cmd.CommandType = CommandType.StoredProcedure;
foreach(PropertyInfo parameter in parameters.GetType().GetProperties())
{
var commandParameter = cmd.CreateParameter();
commandParameter.ParameterName = "#" + parameter.Name;
commandParameter.Value = parameter.GetValue(parameters);
cmd.Parameters.Add(commandParameter);
}
return cmd;
}
}
Callable with a syntax like this:
dal.RunProcedure("dbo.mySP", new {
Parameter1 = value1,
Parameter2 = value2
});
You can greatly simplify the code if you only want to support SqlClient.
But instead of rolling this on your own, use a ready made stable library, such as Dapper.
I ended up with the following solution:
SqlParameter[] parameters = {
new SqlParameter("#p1", SqlDbType.Int) { Value = 999},
new SqlParameter("#p2", SqlDbType.Char, 30, "source") { Value = "test"}
};
da.RunProcedure("[dbo].[SP1]", parameters, out rowsAffected);
The RunProcedure accepts IDataParameter[] parameters and forwards this to an command builder method that adds each single of them into the SqlParameters Property of my SqlCommand object:
private static SqlCommand BuildQueryCommand(string storedProcName, IDataParameter[] parameters)
{
SqlCommand command = new SqlCommand( storedProcName, GetDBConnection() );
command.CommandType = CommandType.StoredProcedure;
if (parameters != null)
{
foreach (SqlParameter parameter in parameters)
{
command.Parameters.Add( parameter );
}
}
return command;
}
This works fine and this way I can add each Param with 1 single line of code (that was my destination #1) incl. all Properties of SqlParameter available (use SqlDBType if required, this is up to the user).
May be this question will be duplicate but I'm unable to find. I'm using signalR and sqldependency for my application. I've performed one query operation successfully. but will i write separate sqldependency code for every query. sqldependency code is on application level or is separate for each query.
1) how to use different query for each operation?
2) how to call different onchange event
public void RegisterNotification()
{ string connectionString = ConfigurationManager.ConnectionStrings["FFFConnention"].ConnectionString;
//We have selected the entire table as the command, so SQL Server executes this script and sees if there is a change in the result, raise the event
// how to use different query for each operation
string commandText = #"
Select
dbo.Notification.UserName
From dbo.Notification
";
//Start the SQL Dependency
SqlDependency.Start(connectionString);
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(commandText, connection))
{
connection.Open();
var sqlDependency = new SqlDependency(command);
NotificationHub hub = new NotificationHub();
//how to call different onchange event
sqlDependency.OnChange += new OnChangeEventHandler(hub.sqlDependency_OnChange);
// NOTE: You have to execute the command, or the notification will never fire.
command.ExecuteScalar();
}
}
}
Is there a way to use simple sql queries on ASP MVC without using LINQ thing?
any link is welcome :)
Of course, you can always drop down to use regular ol' ADO.NET :-)
The Data Access Application Block is also commonly used to simplify the execution of raw sql and stored procedures.
Sure, you can embed plain ADO.NET objects within your controller's action methods or in a custom business logic library. A bit of an example. WARNING: DEMONSTRATION CODE ONLY. DO NOT ATTEMPT TO USE IN PRODUCTION SCENARIO.
public ActionResult Index()
{
using(SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["CNTax"].ConnectionString))
{
using(SqlCommand command = conn.CreateCommand())
{
command.CommandText = "select * from Names";
command.CommandType = CommandType.Text;
conn.Open();
var table = new DataTable();
table.load(command.ExecuteReader());
return View("Index", table);
}
}
}
A simple code snippet to select all names from the database and return the index view with the model set as a DataTable.
You sure can. And it is done the same way as you normally would in an ASP.NET application just like the other answers here have indicated.
....HOWEVER, I prefer to use a tool to generate my data access layer. Some of the top choices right now are nHibernate, and LLBLGen Pro, or even Microsoft's Entity Framework
I personally would go with nHibernate or LLBLGen Pro, depending on if you want to have your data access layer driven by "domain driven design" (nHibernate) or "data driven design" (LLBLGen Pro)
Building off of #user102220's answer:
Set up a data access layer (just a separate class or series of classes), then call these from your controller. Apply ADO.NET as necessary.
If you are using Entity Framework you can use SqlQuery like this:
using(var db = new DbContext())
{
var result = db.Database.SqlQuery<your object>("Your Query",params));
}
Your object : your expected result Type (object or class Type) and
Your query and params : sql command with params you should pass to query or not
try this solution:
var results = DynamicCall.DynamicListFromSql(_entities, "select * from users", null).ToList();
public static IEnumerable<dynamic> DynamicListFromSql(this DbContext db, string Sql, Dictionary<string, object> Params)
{
using (var cmd = db.Database.Connection.CreateCommand())
{
cmd.CommandText = Sql;
if (cmd.Connection.State != ConnectionState.Open) { cmd.Connection.Open(); }
using (var dataReader = cmd.ExecuteReader())
{
while (dataReader.Read())
{
var row = new ExpandoObject() as IDictionary<string, object>;
for (var fieldCount = 0; fieldCount < dataReader.FieldCount; fieldCount++)
{
row.Add(dataReader.GetName(fieldCount), dataReader[fieldCount]);
}
yield return row;
}
}
}
}