Here's the code raising the exception:
public static class NHibernateSessionManager
{
private static ISessionFactory sessionFactory = new Configuration().Configure().BuildSessionFactory();
public static ISession GetSession(string clientId)
{
if (ContextSession == null)
ContextSession = sessionFactory.OpenSession(new OracleIntercerptor(clientId.ToUpper()));
else
((OracleConnection)ContextSession.Connection).ClientId = clientId;
return ContextSession;
}
// - snip -
}
and the call to the code where the exception is raised:
private ISession NHibernateSession
{
get
{
return NHibernateSessionManager.GetSession(SessionWrapper.GetUser());
}
}
I get a TypeInitializationException
{"The type initializer for
'Sigaf.Presupuesto.EntidadesDAL.NHibernate.NHibernateSessionManager'
threw an exception."}
With an inner exception of
{"Could not create the driver from
NHibernate.Driver.OracleDataClientDriver."}
A few more inner exceptions lead me to a NRE:
Object reference not set to an
instance of an object.
at
NHibernate.Driver.OracleDataClientDriver..ctor()
NHibernate v3.0
Target Framework v4.0
This code implementation is working for other, similar, solutions.
Oh, the Hibernate.config file:
<?xml version="1.0"?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="dialect">NHibernate.Dialect.Oracle10gDialect</property>
<property name="current_session_context_class">web</property>
<property name="proxyfactory.factory_class">NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu</property>
<property name="connection.driver_class">NHibernate.Driver.OracleDataClientDriver</property>
<property name="connection.connection_string_name">Sigaf</property>
<property name="default_schema">PRE</property>
<property name="show_sql">true</property>
<mapping assembly="Sigaf.Presupuesto.EntidadesDAL" />
</session-factory>
</hibernate-configuration>
Make sure the actual Oracle driver is in your application bin folder.
In Visual Studio you should add a reference to Oracle.DataAcess.dll in your project for example.
Select the DLL => Right click it => In the Properties grid select Copy Local = True.
This should solve your problem.
Related
Does anybody know why the following code doesn't find any Descendants named "PntList3D" in the XDocument? I've run similar code with xml files from different sources and it's worked just fine.
XDocument xdoc = XDocument.Load(file);
foreach (XElement pntList3D in xdoc.Descendants("PntList3D"))
{
//No XElements found?
string[] coords = pntList3D.Value.Split(separator);
//........
}
The XML file is as follows:
<?xml version="1.0" encoding="iso-8859-1" ?>
<LandXML xmlns="http://www.landxml.org/schema/LandXML-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.landxml.org/schema/LandXML-1.0 http://www.landxml.org/schema/landxml-1.0/LandXML-1.0.xsd" version="1.0" date="2018-05-21" time="10:54:45">
<Units>
<Metric areaUnit="squareMeter" linearUnit="meter" volumeUnit="cubicMeter" temperatureUnit="celsius" pressureUnit="HPA" angularUnit="radians" directionUnit="radians"/>
</Units>
<Application name="Bentley Rail Track V8i (SELECTseries 4)" manufacturer="Bentley Systems, Inc." version="08.11.09.878" manufacturerURL="www.bentley.com"/>
<Surfaces>
<Surface name="GUCanalFinalGround" state="proposed">
<SourceData>
<Breaklines>
<Breakline brkType="standard" name="Merge Boundary Breakline13">
<PntList3D>
373369.843784061 201940.481405058 100.010000000 373346.803045009 201978.937591557 100.266579521 373345.131682429 201986.094864832 100.285820869 373344.675829289 201994.051291911 100.305094741 373343.948058537 202002.377250983 100.325783280 373347.097559184 202015.927410062 100.351677422 373349.064121068 202028.461854698 100.377340245 373349.158000706 202037.105375695 100.397451931 373349.558848160 202047.019625644 100.420035342 373351.626002592 202059.961277642 100.444814507 373351.012091134 202068.660831945 100.465852191 373341.758274428 202103.172391947 100.582514748 373319.443256788 202115.548623449 100.621330067 373314.187088077 202116.429655954 100.632560880 373309.015283797 202117.464532283 100.644344390 373296.621004758 202116.103443765 100.663523942 373291.562007714 202117.732947895 100.675479985 373281.143675082 202119.484060498 100.698356878 373276.337524008 202120.933216769 100.710662078 373272.233432380 202123.836471532 100.724192638 373261.827555133 202125.960550682 100.747355849 373251.520869727 202128.251385445 100.770700659 373245.559103071 202128.214153277 100.781125221 373239.789665844 202128.349784236 100.791427303 373229.601950129 202130.619067512 100.814814992 373225.304350337 202132.986580328 100.828137161 373214.890815224 202136.688095193 100.839157834 373210.210442728 202138.686367756 100.852302328 373204.606106857 202142.207609670 100.866054658 373191.545497214 202148.081237003 100.918005418 373176.562316984 202152.361356766 100.954250454 373171.044645747 202154.053893695 100.966278732 373166.208397576 202155.713237010 100.978687738 373160.708995109 202155.679722689 100.989287494 373155.688534545 202156.493295914 101.000834112 373150.482235484 202157.176413548 101.012161143 373144.212549179 202156.159209438 101.021467326 373137.448440098 202156.600718164 101.031754759 373131.391817655 202156.182136957 101.041765542 373125.390422036 202155.709761447 101.051750480 373119.276552408 202155.069671573 101.061523722 373054.430807066 202143.721890221 102.441500000 373058.442814638 202140.697787490 102.328000000 373066.166069761 202134.158949750 101.933000000 373073.565553867 202127.092819841 101.360000000 373080.608667856 202119.447463058 100.589000000 373087.692942040 202111.870287954 99.839000000 373091.238928264 202108.087310204 99.465000000 373092.286790268 202109.791671688 99.504983646 373095.832728759 202106.008743033 99.130988179 373102.878820288 202098.368395826 98.353988013 373110.583835192 202091.800057704 97.934987722 373118.123075009 202084.962016843 97.421992176 373125.392085793 202077.684336252 96.759009538 373132.990746979 202070.942967185 96.274010799 373140.640127087 202064.284112116 95.814017469 373150.541354297 202061.288814036 96.578880626 373155.592889845 202050.403490658 94.696924444 373161.444949212 202040.820548117 93.249013491 373170.040905925 202035.701685379 93.293999781 373178.501762418 202030.363025321 93.264000224 373187.026261039 202025.127904379 93.265000042 373195.553374235 202019.897036065 93.265999882 373204.080773941 202014.666632815 93.264000015 373212.683146019 202009.558202046 93.299998484 373221.146334288 202004.223330229 93.258000145 373229.732436104 201999.088427042 93.279999413 373238.278154811 201993.887822981 93.277999879 373246.827935106 201988.693825711 93.275000301 373255.419702686 201983.568137077 93.292999519 373270.410218672 201988.852661245 96.796999371 373278.832148334 201983.450659530 96.717001898 373287.478398532 201978.413607052 96.756999575 373296.854035216 201974.563203038 97.191991671 373306.521867266 201971.188175126 97.782985073 373316.068961675 201967.616716606 98.305980919 373325.538253354 201963.918678862 98.785012746 373334.774518673 201959.841526182 99.132990669 373333.727060669 201958.136888591 99.093000000 373342.581640977 201953.439507703 99.231000000 373351.873048413 201949.452662854 99.604000000 373360.885734860 201945.010817605 99.823000000 373369.843784061 201940.481405058 100.010000000
</PntList3D>
<Feature code="Breakline">
<Property label="guid" value="210f4f9d-6f98-4246-8967-4b11eb616339"/>
<Property label="style" value="Default"/>
<Property label="triangulate" value="true"/>
<Property label="pointDensity" value="0.000000000"/>
</Feature>
</Breakline>
<Breakline brkType="standard" name="DB75">
<PntList3D>
373095.450629438 202114.938959557 101.014871165 373092.286790268 202109.791671688 99.504983646
</PntList3D>
<Feature code="Breakline">
<Property label="guid" value="9d937eeb-bcf1-4d51-97c1-080736d60adb"/>
<Property label="style" value="Default"/>
<Property label="triangulate" value="true"/>
<Property label="pointDensity" value="0.000000000"/>
</Feature>
</Breakline>
<Breakline brkType="standard" name="DB74">
<PntList3D>
373054.430807066 202143.721890221 102.441500000 373095.450629438 202114.938959557 101.014871165
</PntList3D>
<Feature code="Breakline">
<Property label="guid" value="71b6272a-99f3-483c-b997-4b3b82de6984"/>
<Property label="style" value="Default"/>
<Property label="triangulate" value="true"/>
<Property label="pointDensity" value="0.000000000"/>
</Feature>
</Breakline>
</Breaklines>
</SourceData>
</Surface>
</Surfaces>
</LandXML>
I couldn't submit this question as apparently I had too much code and not enough detail. I'm pretty sure the amount of detail I provided was adequate so the following text is just to get this question through the Stackoverflow Bots.
Please try the following approach.
The entire XML is bound to a default namespace.
First, you need to get a default namespace just once.
Second, use it any time while referring to the XML element names.
c#
void Main()
{
const string FILENAME = #"e:\Temp\LandXML.xml";
XDocument xdoc = XDocument.Load(FILENAME);
XNamespace ns = xdoc.Root.GetDefaultNamespace();
foreach (XElement pntList3D in xdoc.Descendants(ns + "PntList3D"))
{
Console.WriteLine(pntList3D.Value + Environment.NewLine);
}
}
You need to specify the namespace in your call for Descendants:
foreach (var pntList3D in xdoc.Descendants(XName.Get("PntList3D","http://www.landxml.org/schema/LandXML-1.0")))
{
//No XElements found?
string[] coords = pntList3D.Value.Split(separator);
//........
}
I am accessing my OData service with following metadata (simplified and obfuscated to the relevant part), this is generated by using Microsoft.AspNet.OData :
<Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
<DataServices>
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="MyProject.Api.Models">
<EntityType Name="ValuesContainer">
<Key>
<PropertyRef Name="id" />
</Key>
<Property Name="id" Type="Edm.Guid" Nullable="false" />
<NavigationProperty Name="values" Type="Collection(MyProject.Api.Models.Value)"/>
</EntityType>
<EntityType Name="Value">
<Key>
<PropertyRef Name="id"/>
</Key>
<Property Name="value" Type="Edm.String" />
<Property Name="id" Type="Edm.Guid" Nullable="false" />
<Property Name="valuesContainerId" Type="Edm.Guid"/>
<NavigationProperty Name="valuesContainer" Type="MyProject.Api.Models.ValuesContainer">
<ReferentialConstraint Property="valuesContainerId" ReferencedProperty="id"/>
</NavigationProperty>
</EntityType>
</Schema>
</DataServices>
</Edmx>
Some example the output it generates:
{
"#odata.context": "https://localhost:5002/v1/odata/$metadata#ValuesContainer(values())",
"value": [
{
"id": "2996e6ea-3e72-4b4c-8b3b-b076e34f6dac",
"values": [
{
"value": "Hello world",
"valuesContainerId": "2996e6ea-3e72-4b4c-8b3b-b076e34f6dac",
"id": "3d10fcfa-27a2-4c21-7e01-08d783bf6c40"
}
]
}
]
}
When I try to get a ValuesContainer via using the Simple.Odata.Client I receive the following error:
Microsoft.OData.ODataException: 'The Id cannot be computed, since the navigation source 'values' cannot be resolved to a known entity set from model.'
Part where the exception is thrown:
namespace Simple.OData.Client.V4.Adapter
{
public class ResponseReader : ResponseReaderBase
...
private ODataEntryAnnotations CreateAnnotations(ODataResource odataEntry)
{
string id = null;
Uri readLink = null;
Uri editLink = null;
if (_session.Adapter.GetMetadata().IsTypeWithId(odataEntry.TypeName))
{
try
{
// Over here my exception occurs, calculating the odataEntry.Id.AbsoluteUri
id = odataEntry.Id.AbsoluteUri;
readLink = odataEntry.ReadLink;
editLink = odataEntry.EditLink;
}
catch (ODataException)
{
/// Yep, the library contains this typo
// Ingored
}
}
return new ODataEntryAnnotations
{
Id = id,
TypeName = odataEntry.TypeName,
ReadLink = readLink,
EditLink = editLink,
ETag = odataEntry.ETag,
MediaResource = CreateAnnotations(odataEntry.MediaResource),
InstanceAnnotations = odataEntry.InstanceAnnotations,
};
}
...
}
Is my metadata wrong and/or is there a workaround for this? It's not really required to solve it, but having that many exceptions thrown during runtime causes too much overhead as these are expensive operations.
Found the solution, had to add the Contained attribute to my Value.
I was getting this error, I resolved it by setting:
MergeOption = MergeOption.NoTracking;
on my Client, as I was only doing read-only operations at the time.
Found that answer here: https://github.com/OData/odata.net/issues/2211
I was plagued by this particular error as well. But setting Contained attribute wasn't an option for us. Posting this in case anyone else ever runs into this.
The problem for me was that the IModelConfiguration declaration for my entity's key was silently failing (due to another config setting that was trying to set up an Action incorrectly).
So based on the error from Echamus' original post:
The Id cannot be computed, since the navigation source 'values' cannot be resolved to a known entity set from model
The solution that fixed it for me was making sure the key was defined for the entity type that "values" contains (in this case, ValueModelConfiguration):
using Microsoft.AspNet.OData.Builder;
using Microsoft.AspNetCore.Mvc;
using MyProject.Api.Models;
namespace MyProject.Api.Configuration.Model_Configurations
{
public class ValueModelConfiguration : IModelConfiguration
{
public void Apply(ODataModelBuilder builder, ApiVersion apiVersion)
{
builder.EntitySet<Value>(nameof(Value)).EntityType.HasKey(v => v.id);
// other configurations for your entity (e.g. value) may be here
}
}
}
(Note: Value above is whatever entity for the "navigation source" being complained about in the original error)
If you already have this defined, but you have other configurations occurring before/after it, those other configurations may be the problem and may be causing this particular line to fail silently.
Hope that helps save someone some time in the future.
I am trying to edit a existing XML file through C# and need to identify the sections I want (block name="treeDeadTree01" and block name="treeDeadTree02") Then get the value of "count" in the child element "drop". I have been able to identify the elements (block name="treeDeadTree01" and block name="treeDeadTree02") but cant figure out how to get the value of "count" from the element "drop" of the specific elements (block name="treeDeadTree01" and block name="treeDeadTree02")
The XML file is a config file from the game 7 Days To Die and I am trying to make a application to more easily edit the configs of the game. After I find the value of "count" I am putting it into a DataGridView.
My question is, how after I find the block element I want do I find the value of "count" in the "drop" child element of the block element?
This is a section of the XML file I am trying to edit
<blocks>
<block name="treeDeadTree01">
<property name="Extends" value="treeMaster" />
<property name="Model" value="Entities/Trees/White_Oak22Prefab" />
<property name="ModelOffset" value="0,-0.3,0" />
<property name="MultiBlockDim" value="1,4,1" />
<property name="BigDecorationRadius" value="4" />
<property name="Collide" value="movement,melee,bullet,arrow,rocket" />
<drop event="Harvest" name="resourceWood" count="515" tag="oreWoodHarvest" />
<property name="ParticleOnDeath" value="treeGib_dead_01" />
<!-- <drop event="Destroy" name="treePlantedMaple1m" count="x"/> -->
<property name="SortOrder2" value="0140" />
<!-- SortTree -->
</block>
<block name="treeDeadTree02">
<!-- almost a shrub -->
<property name="Extends" value="treeMaster" />
<property name="IsTerrainDecoration" value="true" />
<property name="Model" value="Entities/Trees/Haunted_Shrub_WastelandPrefab" />
<property name="ModelOffset" value="0,-0.3,0" />
<property name="Collide" value="melee,rocket" />
<!-- no movement effect on Shape="ModelTree" -->
<drop event="Harvest" name="resourceWood" count="215" tag="oreWoodHarvest" />
<property name="ParticleOnDeath" value="treeGib_dead_02" />
<!-- <drop event="Destroy" name="treePlantedMaple1m" count="x"/> -->
<property name="FilterTags" value="foutdoor,ftrees,fshrubbery" />
<property name="SortOrder1" value="a060" />
</block>
</blocks
My current code
string[] GatherRateNames = {"treeDeadTree01", "treeDeadTree02"};
string XMLBlocksPath = "F:\\SteamLibrary\\steamapps\\common\\7 Days To Die\\Data\\Config\\blocks.xml";
private void makeGatherRatesList()
{
XmlDocument doc = new XmlDocument();
doc.Load(XMLBlocksPath);
XmlNodeList aNodes = doc.SelectNodes("/blocks/block");
foreach (XmlNode aNode in aNodes)
{
XmlAttribute idAttribute = aNode.Attributes["name"];
if (GatherRateNames.Contains(idAttribute.ToString()))
{
addItemToList(idAttribute.ToString(),"Value of count");
}
}
}
private void addItemToList(string itemName, int itemValue)
{
}
In the end I want to get the name of the block like "treeDeadTree01" then get the value of "count" inside the element "drop" of that block and put both of those in a DataGridView and be able to edit the value of count through the DataGridView then repeat that with every block I need.
Using Xml Linq :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Globalization;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
CultureInfo culture = (CultureInfo)CultureInfo.InvariantCulture.Clone();
culture.NumberFormat.NumberDecimalSeparator = ",";
culture.NumberFormat.NumberGroupSeparator = ".";
XmlReader reader = XmlReader.Create(FILENAME);
List<Block> blocks = new List<Block>();
while (!reader.EOF)
{
if (reader.Name != "block")
{
reader.ReadToFollowing("block");
}
if (!reader.EOF)
{
Block newBlock = new Block();
blocks.Add(newBlock);
XElement xBlock = (XElement)XElement.ReadFrom(reader);
newBlock.name = (string)xBlock.Attribute("name");
XElement drop = xBlock.Element("drop");
if (drop != null)
{
object count = drop.Attribute("count");
newBlock.count = (count == null)? null : (decimal?)decimal.Parse((string)count, culture);
}
}
}
}
public class Block
{
public string name { get; set; }
public decimal? count { get; set; }
}
}
}
I am trying use NHibernate to my MySQL but I have still issue with connection on my localhost database.
Exeptions:
MySql.Data.MySqlClient.MySqlException
HResult=0x80004005
Message=Unable to connect to any of the specified MySQL hosts.
Source=MySql.Data
StackTrace:
at MySql.Data.MySqlClient.NativeDriver.Open()
at MySql.Data.MySqlClient.Driver.Open()
at MySql.Data.MySqlClient.Driver.Create(MySqlConnectionStringBuilder settings)
at MySql.Data.MySqlClient.MySqlPool.CreateNewPooledConnection()
at MySql.Data.MySqlClient.MySqlPool.GetPooledConnection()
at MySql.Data.MySqlClient.MySqlPool.TryToGetDriver()
at MySql.Data.MySqlClient.MySqlPool.GetConnection()
at MySql.Data.MySqlClient.MySqlConnection.Open()
at NHibernate.Connection.DriverConnectionProvider.GetConnection()
at NHibernate.Tool.hbm2ddl.SuppliedConnectionProviderConnectionHelper.Prepare()
at NHibernate.Tool.hbm2ddl.SchemaMetadataUpdater.GetReservedWords(Dialect dialect, IConnectionHelper connectionHelper)
at NHibernate.Tool.hbm2ddl.SchemaMetadataUpdater.Update(ISessionFactoryImplementor sessionFactory)
at NHibernate.Impl.SessionFactoryImpl..ctor(Configuration cfg, IMapping mapping, Settings settings, EventListeners listeners)
at NHibernate.Cfg.Configuration.BuildSessionFactory()
at TestE.Model.NHibernateHelper.get_Session() in C:\Users\hajek\source\repos\TestE\TestE\NHibernateHelper.cs:line 24
at TestE.Dao.DaoBase1..ctor() in C:\Users\hajek\source\repos\TestE\TestE\Dao\DaoBase.cs:line 20
at TestE.Dao.ItemDao..ctor() in C:\Users\hajek\source\repos\TestE\TestE\Dao\ItemDao.cs:line 13
at TestE.Program.Main(String[] args) in C:\Users\hajek\source\repos\TestE\TestE\Program.cs:line 16
Inner Exception 1:
WaitHandleCannotBeOpenedException: No handle of the given name exists.
Code:
namespace TestE.Model
{
public class NHibernateHelper
{
private static ISessionFactory factory;
private static MySqlConnectionStringBuilder conn_string = new MySqlConnectionStringBuilder();
public static ISession Session
{
get
{
if (factory == null)
{
Configuration cfg = new Configuration();
factory = cfg.Configure("hibernate.cfg.xml").BuildSessionFactory();
}
return factory.OpenSession();
}
}
}
}
hibernate.cfg.xml:
<?xml version="1.0" encoding="utf-8"?>
<!--
This template was written to work with NHibernate.Test.
Copy the template to your NHibernate.Test project folder and rename it in hibernate.cfg.xml and change it
for your own use before compile tests in VisualStudio.
-->
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" >
<session-factory name="TestE">
<property name="connection.driver_class">NHibernate.Driver.MySqlDataDriver</property>
<property name="connection.connection_string">
Database=todo_list;Data Source=localhost;User Id=root;Password=root;
Protocol=memory;Old Guids=True;
</property>
<property name="dialect">NHibernate.Dialect.MySQL5Dialect</property>
</session-factory>
</hibernate-configuration>
Configuration is located in ~/bin/debug and Nhibernate can see it but still can not connect to database.
----- Sorry for my English Language.------
By default, shared memory is not enabled on Windows. This may be why your connection is failing.
Remove Protocol=memory; from your connection string to use a regular TCP/IP connection.
How can I configure NHibernate to connect to both a MySQLserver and a Microsoft SQL server 2008? I do want to copy data from one server to another. I heard of NHibernate shared.
I've struggled quite a bit few months ago.
My problem was with MS Sql Server and Oracle.
What I've done is to create two separate config files for nhibernate:
sql.nhibernate.config
<?xml version="1.0" encoding="utf-8"?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<reflection-optimizer use="false" />
<session-factory name="BpSpedizioni.MsSql">
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
<!-- <property name="connection.connection_string">Data Source=(local); Initial Catalog=NHibernate; Trusted_Connection=true;</property> -->
<property name="current_session_context_class">web</property>
<property name="adonet.batch_size">100</property>
<property name="command_timeout">120</property>
<property name="max_fetch_depth">3</property>
<property name='prepare_sql'>true</property>
<property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
<property name='proxyfactory.factory_class'>NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
<mapping assembly="BpSpedizioni.Services"/>
</session-factory>
</hibernate-configuration>
ora.nhibernate.config
<?xml version="1.0" encoding="utf-8"?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<reflection-optimizer use="false" />
<session-factory name="BpSpedizioni.Oracle">
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.driver_class">NHibernate.Driver.OracleDataClientDriver</property>
<property name="dialect">NHibernate.Dialect.Oracle10gDialect</property>
<!-- <property name="connection.connection_string">Data Source=(local); Initial Catalog=NHibernate; Trusted_Connection=true;</property> -->
<property name="current_session_context_class">web</property>
<property name="adonet.batch_size">100</property>
<property name="command_timeout">120</property>
<property name="max_fetch_depth">3</property>
<property name='prepare_sql'>true</property>
<property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
<property name='proxyfactory.factory_class'>NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
<mapping assembly="BpSpedizioni.Services"/>
</session-factory>
</hibernate-configuration>
I use this simple class to build my nhibernate SessionFactory:
public class NHibernateSessionFactory
{
private ISessionFactory sessionFactory;
private readonly string ConnectionString = "";
private readonly string nHibernateConfigFile = "";
public NHibernateSessionFactory(String connectionString, string nHConfigFile)
{
this.ConnectionString = connectionString;
this.nHibernateConfigFile = nHConfigFile;
}
public ISessionFactory SessionFactory
{
get { return sessionFactory ?? (sessionFactory = CreateSessionFactory()); }
}
private ISessionFactory CreateSessionFactory()
{
Configuration cfg;
cfg = new Configuration().Configure(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, this.nHibernateConfigFile));
// With this row below Nhibernate searches for the connection string inside the App.Config.
// cfg.SetProperty(NHibernate.Cfg.Environment.ConnectionStringName, System.Environment.MachineName);
cfg.SetProperty(NHibernate.Cfg.Environment.ConnectionString, this.ConnectionString);
#if DEBUG
cfg.SetProperty(NHibernate.Cfg.Environment.GenerateStatistics, "true");
cfg.SetProperty(NHibernate.Cfg.Environment.ShowSql, "true");
#endif
return (cfg.BuildSessionFactory());
}
}
As you can see I pass to my NHibernateSessionFactory a connection string (I prefer to save it in my app config file) and the name (without the path) of the nhibernate config file.
I personally use a DI container (StructureMap) and you can achieve something very cool defining a registry class:
public class NhibernateRegistry : Registry
{
public NhibernateRegistry()
{
For<ISessionFactory>()
.Singleton()
.Add(new NHibernateSessionFactory(<oracle connection string>, "ora.nhibernate.config").SessionFactory)
.Named("OracleSF");
For<ISession>()
.HybridHttpOrThreadLocalScoped()
.Add(o => o.GetInstance<ISessionFactory>("OracleSF").OpenSession())
.Named("OracleSession");
For<ISessionFactory>()
.Singleton()
.Add(new NHibernateSessionFactory(<ms sql connection string>, "sql.nhibernate.config").SessionFactory)
.Named("MsSqlSF");
For<ISession>()
.HybridHttpOrThreadLocalScoped()
.Add(o => o.GetInstance<ISessionFactory>("MsSqlSF").OpenSession())
.Named("MsSqlSession");
}
}
in which you can use named instances.
My services layer than uses a StructureMap registry class where you can define the constructors:
this.For<IOrdersService>()
.HybridHttpOrThreadLocalScoped()
.Use<OrdersService>()
.Ctor<ISession>("sessionMDII").Is(x => x.TheInstanceNamed("OracleSession"))
.Ctor<ISession>("sessionSpedizioni").Is(x => x.TheInstanceNamed("MsSqlSession"));
For your Service implementation:
public class OrdersService : IOrdersService
{
private readonly ISession SessionMDII;
private readonly ISession SessionSpedizioni;
public OrdersService(ISession sessionMDII, ISession sessionSpedizioni)
{
this.SessionMDII = sessionMDII;
this.SessionSpedizioni = sessionSpedizioni;
}
...
}
It's not clear what your use case is, but you will simply need to create 2 session factories. One will use your mySQL dialect, connection string, etc... and the other will use the SQL Server equivalents.
Just avoid including any custom SQL in your mappings and this should work fine.