I'm trying to get a grasp of using spring.net ioc to suit my purpose.
What options to using xml configuration (metadata file) are available in spring.net ioc. i.e. i don't want to use the following:
<object name="MyMovieFinder"
type="Spring.Examples.MovieFinder.SimpleMovieFinder,
Spring.Examples.MovieFinder"/>
</object>
Instead, i want to load this values from a database like below:
SqlCommand cmd = new SqlCommand("select ObjName, ObjType, ObjPath from tblApp", cn)
SqlDataReader dr = cmd.ExecuteReader();
while(dr.read)
IApplicationContext ctx = ContextRegistry.GetContext();
MovieLister lister = (MovieLister) ctx.GetObject (dr["ObjName"]);
If you want to store your object definitions in a database and use that to power your application you should look at the IResource interface, there's a chapter on it in the Spring.NET documentation here.
Related
How to make database connection in ASP.NET core with postgres SQL ?
Question: How to make database connection in ASP.NET core with postgres SQL ?
There are two ways you add your postgresql database along with the asp.net core project.
Using follwing way:
ADO.net connection provider
Nuget extension: Npgsql.EntityFrameworkCore.PostgreSQL
ADO.net connection provider
Here would just need the NpgsqlConnection connection builder class which will execute your sql on Postgre sql database server. See the example below:
C# ASP.NET Core & Postgre SQL Ado.net example:
NpgsqlConnection conn = new NpgsqlConnection("Server=127.0.0.1;User Id=postgres;Password=pwd;Database=postgres;");
conn.Open();
// Passing PostGre SQL Function Name
NpgsqlCommand command = new NpgsqlCommand("EXE GetEmployeePrintInfo", conn);
// Execute the query and obtain a result set
NpgsqlDataReader reader = command.ExecuteReader();
// Reading from the database rows
List<string> listOfManager = new List<string>();
while (reader.Read())
{
string WSManager = reader["WSManager"].ToString(); // Remember Type Casting is required here it has to be according to database column data type
listOfManager.Add(WSManager);
}
reader.Close();
command.Dispose();
conn.Close();
Npgsql.EntityFrameworkCore.PostgreSQL:
You have to add Nuget extension into the project reference from manage Nuget Packages using Visual studio. Entity framework core has this functionality for many database providers. Just follow below steps on visual studio
ConfigureServices in startup.cs:
Once you successfully added the Nuget package then you have to update following code on your project ConfigureServices under startup.cs
services.AddDbContext<YourDatabaseContextClassName>(options =>
options.UseNpgsql(Configuration.GetConnectionString("YourDatabaseContextStringNameFromAppsettings")));
Note: If you need any example for entityframework and Postgre SQL implementation you can have look here
For further assistance you can have look on official document here. Hope it would guide you accordingly.
So, I recently asked a question about a class called SQLHelper, that was designed to cut down duplicated code whenever you connect to a SQL server, create a stored procedure command, etc.
Essentially, from this:
string connectionString = (string)
ConfigurationSettings.AppSettings["ConnectionString"];
SqlConnection connection = new SqlConnection(connectionString);
SqlCommand command = new SqlCommand("INSERT_PERSON",connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#Name",SqlDbType.NVarChar,50));
command.Parameters["#Name"].Value = txtName.Text;
command.Parameters.Add(new SqlParameter("#Age",SqlDbType.NVarChar,10));
command.Parameters["#Age"].Value = txtAge.Text;
connection.Open();
command.ExecuteNonQuery();
connection.Close();
...it would do this:
SqlHelper.ExecuteNonQuery(connection,"INSERT_PERSON",
new SqlParameter("#Name",txtName.Text), new SqlParameter("#Age",txtAge.Text));
Unfortunately the SQLHelper class vanished and is not available anymore in Enterprise library.
Would anybody know what could I use to avoid long code to set the connection up, create a store procedure, create parameters, set them, open the connection, execute the command and close the connection?
This would be required in each method that accesses that database and therefore is a considerable amount of duplicated code.
Is there way to avoid this?
I have a need to generate SQL queries against a variety of database providers, for database schemas that are not known at compile time. I see that Entity Framework has already done the hard work of providing a SQL dialect called Entity SQL that is translated to native SQL before execution, and I was hoping to take advantage of that in some way.
Ideally, I'd like to just generate ESQL, run it, and get an IDataReader, while Entity Framework worries about the provider-specific details. However, there doesn't seem to be a way to create an EntityConnection without providing metadata in the form of SSDL, CSDL, and MSL files, and I won't find out about the database schema until runtime.
My question is, is there any way to take advantage of ESQL without any information about the database schema at compile time? If necessary (and possible), I would be open to programmatically generating the metadata from the database and caching it. I would also be open to any .NET tools that might be a better fit for my needs than Entity Framework.
Thanks for your time.
Update
Thanks to Alex's suggestion, I've been able to work out how to generate the metadata needed for an EntityConnection on the fly, without writing out any files. As a result, I've been able to do exactly what I was hoping. Now all I need to do is figure out how to extract information about available tables/views for my own use from the generated metadata.
Here's my test code:
#r "System.Data.Entity"
#r "System.Data.Entity.Design"
#r "System.Transactions"
open System
open System.IO
open System.Data
open System.Data.EntityClient
open System.Data.Entity.Design
open System.Data.Mapping
open System.Data.Metadata.Edm
open System.Data.SqlClient
open System.Text
open System.Xml
let dbName = "Northwind"
let cnstr = sprintf "Server=.;Database=%s;Integrated Security=SSPI" dbName
let provider = "System.Data.SqlClient"
let mslText = StringBuilder()
let mslWriter = XmlWriter.Create(mslText)
let schemaGen = EntityStoreSchemaGenerator(provider, cnstr, dbName)
schemaGen.GenerateStoreMetadata() |> ignore
let modelGen = EntityModelSchemaGenerator(schemaGen.EntityContainer)
modelGen.GenerateMetadata() |> ignore
modelGen.WriteStorageMapping(mslWriter)
mslWriter.Close()
let mslReader = XmlReader.Create(new StringReader(mslText.ToString()))
let ssdlCollection = schemaGen.StoreItemCollection
let csdlCollection = modelGen.EdmItemCollection
let mslCollection = StorageMappingItemCollection(csdlCollection, ssdlCollection, [| mslReader |])
let mdw = MetadataWorkspace()
mdw.RegisterItemCollection(csdlCollection)
mdw.RegisterItemCollection(ssdlCollection)
mdw.RegisterItemCollection(mslCollection)
let sqlCn = new SqlConnection(cnstr)
let cn = new EntityConnection(mdw, sqlCn)
let cmd = cn.CreateCommand()
cmd.CommandText <- sprintf "SELECT p.ProductName FROM %sContext.Products AS p" dbName
cn.Open()
let reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)
while reader.Read() do
printfn "%A" reader.["ProductName"]
reader.Close()
cn.Close()
sqlCn.Close()
There is a way to create an EntityConnection by pointing at appropriate metadata (CSDL, MSL and SSDL) at runtime.
In fact that is one of the key benefits of dropping down from the Object Layer (CLR classes) to the Entity Client (eSQL and DataReaders etc).
To help you get started this This post shows you how to create an EntityConnection at runtime.
Background: I am using Nhibernate in an ASP.NET MVC application with an open-session-in-view pattern and I need to use raw ADO.NET to execute some performance-critical database operations.
I'm somewhat confused about how I should be getting my connection instance as I've seen two different methods in numerous blog posts.
Do I want to use:
var connection = Session.Connection;
Or:
var connection = ((ISessionFactoryImplementor)sessionFactory).ConnectionProvider.GetConnection();
I can't seem to find a conclusive answer anywhere and I'm hoping that someone with some extensive NHibernate experience can chime in here.
If you already have a session, use the connection from it.
That will also allow you to share the transaction (if one is open) by enlisting your commands on it.
i'm using something in the lines of (also uses the underlying already-open transaction)
SqlCommand command = new SqlCommand(updateString, (SqlConnection)NHibernateSession.Connection);
command.Parameters.AddRange(parameters.ToArray());
try
{
ITransaction tx = NHibernateSession.Transaction;
tx.Enlist(command);
command.ExecuteNonQuery();
}
catch (SqlException)
{
NHibernateSessionManager.Instance.RollbackTransaction();
throw;
}
We have 3 databases providers we use to connect to our databases: DB2, MS SQL, and Interbase. I would like to create a single generic database wrapper class that can be used to talk to all three just by passing in the correct connection string, username, password, and the provider desired.
I don't want to have to add references and import all three providers in the database class. Is this possible?
I have done this before in Java using the Class.forName() function.
There is an abstract factory built into .NET 2.0 or later, an example of its use would be:
Dim factory As System.Data.Common.DbProviderFactory
factory = System.Data.Common.DbProviderFactories.GetFactory("System.Data.SqlClient")
Dim conn As System.Data.Common.DbConnection = factory.CreateConnection()
conn.ConnectionString = "connectionString"
conn.Open()
There are methods on DbProviderFactory like CreateCommand, CreateDataAdapter, etc.
If you do not want to have references to the individual providers in your application, you will need to handle this a little differently.
There are two main options I see - the first (and easiest) would be to use a dependency injection framework to just plugin the appropriate provider at runtime. This is simple, clean, and works well.
You could do it yourself without that, though. Just make a general purpose base class that provides the interface, and, for each provider, make a separate assembly (so the references are separated) that implements this base class. You can then use Activator.CreateInstance to create an instance of the appropriate type at runtime.
To expand on Patrick McDonald's answer, you can store the provider name and connection string in the <connectionStrings> section of your application configuration file. Then you don't need to have the providers hardcoded in the application:
ConnectionStringSettings c = ConfigurationManager.ConnectionStrings["MyConnectionName"];
if (c != null)
{
DbProviderFactory factory = DbProviderFactories.GetFactory(c.ProviderName);
IDbConnection connection = factory.CreateConnection();
connection.ConnectionString = c.ConnectionString;
...
}
Where your application configuration file contains a connectionStrings section something like:
<connectionStrings>
<add name="MyConnectionName" providerName="System.Data.SqlClient" connectionString="Data Source=serverName;Initial Catalog=DBName;Integrated Security=True"/>
</connectionStrings>
can you use framework 3.5 sp1?
if yes, you should look at Linq to Entity