Castle Active Record Multiple Database Connections (Oracle and SQL) - c#

Scenario: I have an application that pulls data from a SQL database as well as an Oracle database. I have NHibernate implemented for the SQL side and a co-worker already has a working implementation of the Oracle side (same object different project). I am currently defining a connection string in App.Config and calling this function in Program.cs
var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["Foo"].ToString();
var configuration = InPlaceConfigurationSource.Build(DatabaseType.MsSqlServer2000, connectionString);
ActiveRecordStarter.Initialize(System.Reflection.Assembly.GetExecutingAssembly(), configuration);
Note the project is in C# .Net 3.5
I have read about using DifferentDatabaseScope but when I try that the queries don't return any results nor can I see anything in the NHib Profiler. No errors pop up just 0 count.
Question: How do I implement multiple connections?

For future users who come across this problem.
This article helps http://www.darkside.co.za/archive/2008/01/21/castle-activerecord-connecting-to-multiple-databases.aspx
To get this to work I had to add these code snippets to my App.config
<activerecord>
<config>
<add key="connection.driver_class"
value="NHibernate.Driver.OracleClientDriver" />
<add key="dialect"
value="NHibernate.Dialect.Oracle10gDialect" />
<add key="connection.provider"
value="NHibernate.Connection.DriverConnectionProvider" />
<add key="connection.connection_string"
value="Data Source =
(DESCRIPTION =
(ADDRESS =
(PROTOCOL = TCP)
(HOST = SERVERNAME)
(PORT = 1521)
)
(ADDRESS =
(PROTOCOL = TCP)
(HOST = SERVERNAME)
(PORT = 1521)
)
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = NAME)
)
);User Id = ID; Password = PASS;" />
</config>
And this
<config type="Sens.SensClass`1, Sens">
<add key="connection.driver_class"
value="NHibernate.Driver.SqlClientDriver" />
<add key="dialect"
value="NHibernate.Dialect.MsSql2000Dialect" />
<add key="connection.provider"
value="NHibernate.Connection.DriverConnectionProvider" />
<add key="connection.connection_string"
value="Data Source=mntcon016\;Initial Catalog=TEST;Trusted_Connection=True;" />
</config>
</activerecord>
<configSections>
<section name="activerecord"
type="Castle.ActiveRecord.Framework.Config.ActiveRecordSectionHandler, Castle.ActiveRecord" />
<section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate"/>
</configSections>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="proxyfactory.factory_class"> NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle </property>
</session-factory>
</hibernate-configuration>
Then in Program.cs before Application.Run I have
ActiveRecordStarter.Initialize(
ActiveRecordSectionHandler.Instance, types.ToArray());
Where types is a list(function requires an array) of type[]. This list needs to contain every class that will be used with Nhibernate. In my case it contains both the SQL and Oracle classes. As well as this class that is inherited by all my SQL classes
public abstract class TestClass<T> : ActiveRecordBase<T>
{
}
To generate my SQL classes I had used a generator and it made them all Serializable which had to be taken off. Also note that you cannot have classes with the same name or you will get an error.

Related

How to configure App.config to remove Serilog.Sinks.MSSqlServer standard columns?

I use Serilog for logging. I need to configure App.config as to remove 2 standard columns from Logs table (StandardColumn.Properties and StandardColumn.MessageTemplate). I've searched for it in Serilog docs and other resources but can't find how to do it. This is what I got so far:
<configuration>
<appSettings>
<add key="serilog:using:MSSqlServer" value="Serilog.Sinks.MSSqlServer" />
<add key="serilog:write-to:MSSqlServer.connectionString" value="Data Source=SomeServer;initial catalog=DB; integrated security=True" />
<add key="serilog:write-to:MSSqlServer.tableName" value="Logs" />
<add key="serilog:minimum-level" value="Debug" />
</appSettings>
</configuration>
I guess I would have to add this line:
<add key="serilog:write-to:MSSqlServer.columnOptions" value="someColOptions" />
but how should I define someColOptions? For example, I removed columns using this kind of code:
var colOptions = new Serilog.Sinks.MSSqlServer.ColumnOptions();
colOptions.Store.Remove(StandardColumn.Properties);
colOptions.Store.Remove(StandardColumn.MessageTemplate);
Log.Logger = new LoggerConfiguration()
.WriteTo
.MSSqlServer(
connectionString: conn_string,
sinkOptions: new MSSqlServerSinkOptions { TableName = "Logs" },
columnOptions: colOptions)
.MinimumLevel.Debug()
.CreateLogger();
and now I want to do the same in App.config
I had a similar question, I've been able to find out that by adding the following, the configSections has to be first section after
that this will:
create a Logs table in the specified Database (from the connection string)
Use the Serilog database account (from the connection string)
Remove the column called Properties from the Logs table
Add a new column called RunId that declared as an int
<configuration>
<configSections>
<section name="MSSqlServerSettingsSection" type="Serilog.Configuration.MSSqlServerConfigurationSection, Serilog.Sinks.MSSqlServer"/>
</configSections>
<MSSqlServerSettingsSection DisableTriggers="false" ClusteredColumnstoreIndex="false" PrimaryKeyColumnName="Id">
<!-- SinkOptions parameters -->
<TableName Value="Logs"/>
<BatchPeriod Value="00:00:15"/>
<RemoveStandardColumns>
<remove Name="Properties"/>
</RemoveStandardColumns>
<Columns>
<add ColumnName="RunId" DataType="int"/>
</Columns>
</MSSqlServerSettingsSection>
<appSettings>
<!-- Serilog Settings -->
<add key="serilog:minimum-level" value="Verbose" />
<add key="serilog:using:Console" value="Serilog.Sinks.Console"/>
<add key="serilog:write-to:Console"/>
<add key="serilog:using:File" value="Serilog.Sinks.File" />
<add key="serilog:write-to:File"/>
<add key="serilog:write-to:File.path" value="{PATH}" />
<add key="serilog:write-to:File.rollingInterval" value="Day"/>
<add key="serilog:using:MSSqlServer" value="Serilog.Sinks.MSSqlServer" />
<add key="serilog:write-to:MSSqlServer.connectionString" value="Server=[SERVER];Database=[DATABASE];User Id=Serilog;Password=[PASSWORD];"/>
<add key="serilog:write-to:MSSqlServer.tableName" value="Logs"/>
<add key="serilog:write-to:MSSqlServer.autoCreateSqlTable" value="true"/>
</appSettings>
</configuration>
Calling Log.("{RunId}{Message}", _runId, _messageToShow) causes my File, Console AND MSSqlServer sinks to execute writing to these, if it doesn't exist the Logs table will be created, removing the Properties column and adding the RunId column. (If the table exists it doesn't do anything but write the data, still trying to work out how to handle that).
I'm still playing around with this (my next thing is to work out how to write {RunId} but not have it appear in the log, only written to the corresponding database field).
HTH,
Phil

Can't read database name web project

Trying to read the database name but it's not working in the site. Using an asp.net web project with a solution file. I put this in the web.config. This will change depending on development database or production database PRODDB via the web configuration transform files and scripts.
<appSettings>
<add key="databaseName" value="DEVELDB"/>
<add key="operatingEnvironment" value="dev"/>
</appSettings>
Within the Global.asax.cs file:
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
var operatingEnvironment = WebConfigurationManager.AppSettings["operatingEnvironment"].ToString();
if (operatingEnvironment == "dev")
{
Application["DBE"] = WebConfigurationManager.AppSettings["databaseName"].ToString();
}
}
Within the login.cs class file:
internal static DatabaseConnection GetDatabaseConnection()
{
return
new DatabaseConnection(
new ConnectionProperties
{
User = Shared.User,
Application = Shared.Application,
DatabaseName = (string)HttpContext.Current.Application["DBE"]
});
}
and within the Web.Development.config file there is:
<appSettings>
<add key="databaseName" value="DEVELDB" xdt:Transform="SetAttributes" xdt:Locator="Match(key)" />
<add key="operatingEnvironment" value="dev" xdt:Transform="SetAttributes" xdt:Locator="Match(key)" />
</appSettings>
However, whenever I debug after login, it goes to the code below which is good (the same as coded above) but says Database name was not specified? I have it specified as DEVELDB and using "DBE" to reference it. However, it's not like it debugs to another area and to there, just straight to there and kills it?
...
{
User = Shared.User,
Application = Shared.Application,
DatabaseName = (string)HttpContext.Current.Application["DBE"]
});
Connections to databases go inside the "connectionstrings" tags in you "webconfig" file. If you need SqlServer it is shown below
<configuration>
<connectionStrings>
<add name="TwoWayConn" connectionString="Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\TwoWayData.accdb"
providerName="System.Data.OleDb" />
<add name="TWOWAYDATASQL" connectionString="Data Source=TBIRD\SQLEXPRESS1;Initial Catalog=TWOWAYDATASQL.MDF;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
....
</configuration>
Am I misunderstanding what you are trying to do?

NHibernate BuildSessionFactory() ArgumentException: Keyword not supported: 'initial catalog'

I am building a ASP.NET MVC project and am using NHibernate instead of Entity Framework.
The problem that am experiencing is that I get an ArgumentException: Keyword not supported: 'initial catalog' when calling the BuildSessionFactory() method in the Configuration object.
config = new Configuration();
config.Configure();
sessionFactory = config.BuildSessionFactory();
session = sessionFactory.OpenSession();
IList<Catalogue> catalogues = (from c in session.Query<Catalogue>()
select c).ToList();
return this.Json(catalogues, JsonRequestBehavior.AllowGet);
My Connection String is
<property name="connection.connection_string">Data Source=.\SQLEXPRESS;Initial Catalog=Passion4Performance;Integrated Security=True</property>
I have tried many solution but nothing seems to fix this.
Thank you in advance.
Your config file should look something like this:
<connectionStrings>
<add name="NameOfConnectionString" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=Passion4Performance;Integrated Security=True" />
</connectionStrings>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.connection_string_name">NameOfConnectionString</property>
</session-factory>
</hibernate-configuration>

Changing connection string in app.config for Entity Framework

I am using Entity Framework. In app.config there is stored connection string that EF generates for my database.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
</configSections>
<connectionStrings>
<add name="votemeEntities" connectionString="metadata=res://*/VoteModel.csdl|res://*/VoteModel.ssdl|res://*/VoteModel.msl;provider=MySql.Data.MySqlClient;provider connection string="server=localhost;User Id=root;database=voteme""
providerName="System.Data.EntityClient" />
<add name="VoteMe.Properties.Settings.votemeConnectionString"
connectionString="server=localhost;User Id=root;database=voteme"
providerName="MySql.Data.MySqlClient" />
</connectionStrings>
</configuration>
I need to set Charset in this connection string. How do I do it so my EF use this connection string without any problems?
Thanks
You can add the property at the end of the EF connection string, just before the ".
...abase=voteme;charset=UTF8;""
providerName="System.Data.EntityClient" />
Just make sure that the value is properly XML escaped (if needed), otherwise you will break the config file.

How to declare a variable in the app.config file?

I am working on a Windows application.
I have a form with labels like
HOST:
UserName:
Password:
How I can declare the connection string in the app.config file so that it takes the initial catalog, userID and password as variables that I can use in further to check the user whether which database the user wants to get connected with the entered userID and password.
I am using SQL Server 2008 and Visual C# 2008 Express Edition.
As I'm reading your question, you want to have a generic connection string that you want to inject username/password variables into. To do that you would need to have a key with this format:
<add name="myDBKey" connectionString="Data Source=myDB;Initial Catalog={0};Persist Security Info=True;User ID={1};Password={2}" providerName="System.Data.SqlClient"/>
Then in your code, you would need to have these variables declared and assigned, and then use String.Format to complete it.
string dbCatalog = "myCatalog";
string dbUser = "myUser";
string dbPW = "myPW";
string myDBConnectionString = String.Format(
ConfigurationManager.ConnectionStrings["myDBKey"].ConnectionString,
dbCatalog, dbUser, dbPW);
This will inject your variables into the string.
There is a <connectionString> section to the app.config file.
<connectionStrings>
<add name="MyDatabase" connectionString="Data Source=sqlserver,1433;Network Library=DBMSSOCN;Initial Catalog=MyDatabase;User ID=xxx;Password=xxxx;" />
</connectionStrings>
For your Host, User ID and Password, you can define these in the <appSettings> section.
Try this
<connectionStrings>
<add name="ConString" connectionString="Server=Servernae;Database=DBName;User Id=username;password=yourpassword"/>
</connectionStrings>
For more information try Connection Strings
Start by declaring the variables by going to your project's property tab, then going to the Settings tab (on the left), declaring your variables by mentioning the name, default value, and scope (which will be Application).
In your code, to fetch the values:
using System.Configuration;
//....
ConfigurationSettings.AppSettings["ConnectionString"].ToString();
// or
ConfigurationSettings.AppSettings.ConnectionString;
Please note that you can't change the value in code for an Application setting.
EDIT:
Alternately, there is also the connectionStrings node which can be set (but it must be done in the app.config file itself. See MSDN for documentation.
Example of XML:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="ConnStr1" connectionString="LocalSqlServer: data source=127.0.0.1 Integrated Security=SSPI;Initial Catalog=aspnetdb"
providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
In C#, you will get a System.Coonfiguration.ConnectionStrings, which is a collection of ConnectionStringSettings.
Example of usage in C# code: http://msdn.microsoft.com/en-us/library/system.configuration.configurationmanager.connectionstrings.aspx
You can do some thing like this,
<appSettings>
<add key="SettingName" value="SettingValue" />
</appSettings>
or go to "Variables within app.config/web.config".
My library Expansive is designed with this as a primary use-case.
Moderate Example (using AppSettings as default source for token expansion)
In app.config:
<configuration>
<appSettings>
<add key="Domain" value="mycompany.com"/>
<add key="ServerName" value="db01.{Domain}"/>
</appSettings>
<connectionStrings>
<add name="Default" connectionString="server={ServerName};uid=uid;pwd=pwd;Initial Catalog=master;" provider="System.Data.SqlClient" />
</connectionStrings>
</configuration>
Use the .Expand() extension method on the string to be expanded:
var connectionString = ConfigurationManager.ConnectionStrings["Default"].ConnectionString;
connectionString.Expand() // returns "server=db01.mycompany.com;uid=uid;pwd=pwd;Initial Catalog=master;"
or
Use the Dynamic ConfigurationManager wrapper "Config" as follows (Explicit call to Expand() not necessary):
var serverName = Config.AppSettings.ServerName;
// returns "db01.mycompany.com"
var connectionString = Config.ConnectionStrings.Default;
// returns "server=db01.mycompany.com;uid=uid;pwd=pwd;Initial Catalog=master;"
Advanced Example 1 (using AppSettings as default source for token expansion)
In app.config:
<configuration>
<appSettings>
<add key="Environment" value="dev"/>
<add key="Domain" value="mycompany.com"/>
<add key="UserId" value="uid"/>
<add key="Password" value="pwd"/>
<add key="ServerName" value="db01-{Environment}.{Domain}"/>
<add key="ReportPath" value="\\{ServerName}\SomeFileShare"/>
</appSettings>
<connectionStrings>
<add name="Default" connectionString="server={ServerName};uid={UserId};pwd={Password};Initial Catalog=master;" provider="System.Data.SqlClient" />
</connectionStrings>
</configuration>
Use the .Expand() extension method on the string to be expanded:
var connectionString = ConfigurationManager.ConnectionStrings["Default"].ConnectionString;
connectionString.Expand() // returns "server=db01-dev.mycompany.com;uid=uid;pwd=pwd;Initial Catalog=master;"

Categories

Resources