Starting with NHibernate - c#

I'm having major difficulties to start off with NHiberante.
Main problems:
Where my hbm.xml files should reside? I create a Mappings folder but I received an error "Could not find xxx.hbm.xml file."
I tried to load the specific class through the dialect cf.AddClass(typeof(xxx)); but it still gives me the same error (the files are marked as embebed resources.
Also I'm having major problems in connection to it. I stopped trying to use the cfg xml file and tried a more direct approach with a library I have here.
Configuration cfg = new Configuration();
cfg.AddClass(typeof(Tag));
ISessionFactory sessions = cfg.BuildSessionFactory();
AgnosticConnectionHandler agch = new AgnosticConnectionHandler("xxx","xxx","geo_biblio","localhost",
5432,DatabaseInstance.PostgreSQL);
ISession sessao = sessions.OpenSession(agch.GetConnection);
ITransaction tx = sessao.BeginTransaction();
Tag tag1 = new Tag();
tag1.NomeTag = "Teste Tag NHibernate!!!";
sessao.Save(tag1);
tx.Commit();
sessao.Close();
Any tips for me? I'm getting the exception in line 2 of this code, and still not sure what to do.
Any help is appreciated. Thanks

If you're starting with nHibernate I think you really should take a look at fluent nhibernate, its way easier do develop and maintain the mapping, it even has an auto-mapping option.
Another option is confORM from Fabio Maulo (nhibernate lead developer), looks like a great tool.
Also, you can take a look at s#arp architecture, you can get some nice ideas from this project.

Related

Entity Framework, SQLite and Lazy loading

Hi I had developed a C# Budget application using SQL Compact and EF4, I created the EF model through the VS2010 Entity Data Model template. It is all working very well. However I am considering developing a iPhone app to support cash transactions and thought it would be better to have the back end DB supported on both platforms. After creating the SQLite DB and creating a new model I have come across a problem when trying to access referenced data via the Navigation properties in my model. I am getting a NullReferenceException when trying to display a property of a referenced table.
When using the following code I get the exception on the last line:
BudgetEntities budget = new BudgetEntities();
var accounts = budget.BankAccounts.ToList();
foreach (BankAccount a in accounts)
{
Console.WriteLine("Name:" + a.Description);
Console.WriteLine("Number:" + a.AccountNumber);
Console.WriteLine("Type:" + a.BankAccountType.AccountType); //Exception occurs here.
}
Strange thing is that the exception doesn't occur in this example. I'm not sure what is going on?
BudgetEntities budget = new BudgetEntities();
var accoutTypes = budget.BankAccountTypes;
var account = new BankAccount();
account.ID = Guid.NewGuid();
account.AccountTypeID = accoutTypes.First(t => t.AccountType.StartsWith("Credit")).ID;
account.BSB = "3434";
account.AccountNumber = "32323";
account.Description = "Test";
account.TrackingAccount = true;
budget.AddObject("BankAccounts", account);
budget.SaveChanges();
var accounts = budget.BankAccounts.ToList();
foreach (BankAccount a in accounts)
{
Console.WriteLine("Name:" + a.Description);
Console.WriteLine("Number:" + a.AccountNumber);
Console.WriteLine("Type:" + a.BankAccountType.AccountType); //Exception doesn't happen.
}
This is only a simple example and I know I could fix it by adding .Include("BankAccountTypes") to the query however I have other queries that are quite complex that are creating object which include properties from referenced object with in the query and I am not quite sure how to get around this issue for them.
EDIT:
After having a break between projects I have come back to this problem and I have finally resolved my problem. it had nothing to do with the code. It was with the data. I had converted a SQL Compact database to SQLite via a dump and load and had the syntax wrong for my Guid column data. I was inserting the Guid as '7cee3e1c-7a2b-462d-8c3d-82dd6ae62fb4' when it should have been x'7cee3e1c7a2b462d8c3d82dd6ae62fb4'
Hopefully the hair I pulled out working through this problem will grow back :)
Thanks everyone for your input.
In second example your code snippet begins with:
var accoutTypes = budget.BankAccountTypes;
This loads all bank account types to your application and you don't need lazy loading anymore (EF will automatically recognize that these entities were already loaded and fix relations with bank accounts).
First check if your account class is dynamic proxy (just check type of a in the debugger). If it is not you made some mistake in the class definition and lazy loading will not work. Next check if lazy loading is enabled on your context instance (budget.ContextOptions.LazyLoadingEnabled property).
Make sure the BankAccountType property is declared virtual in BudgetEntities.

vmware .net api help vmware.vim.dll problems

Vmware's .net api reference is somewhat confusing and hard to follow. I have been able to connect to my vcenter host then get a list of esxi hosts. Then I have been able get all the running modules on the host using HostKernelModuleSystem, and probe the properties on the variable "mod"... but I am not able to figure out how to get license info, I tried creating an object lic below, trying all different kinds of "types" from vmware with the word license in the type. but, it never works it has a problem converting the line with LicenseManagerLicenseInfo lic = .... I always get the following:
"Cannot convert type 'Vmware.Vim.Viewbase' to
'Vmware.Vim.LicenseManagerLicenseInfo'"
but the declaration above it for "mod" works fine.
I have also tried:
HostLicenseConnectInfo
LicenseAssignmentManagerLicenseAssignment
LicenseManager
I am hoping someone who has worked with vmware .net api can shed some light on what i am doing wrong? I am new to C# about 1 year :) but these VMware APIs are somewhat confusing to me.
esxList = client.FindEntityViews(typeof(HostSystem), null, null, null);
foreach (HostSystem host in esxList)
{
HostKernelModuleSystem mod = (HostKernelModuleSystem)client.GetView(host.ConfigManager.KernelModuleSystem, null);
LicenseManagerLicenseInfo lic = (LicenseManagerLicenseInfo)client.GetView(host.ConfigManager.LicenseManager, null);
string name = lic.Name;
}
I'll have to go to work tomorrow to look at this ( don't have ESX and VMWare SDK for .NET at home ) but I've done a bit of this work.
I wrote a generics method that wraps FindEntityViews and takes a filter as an argument. That makes it easy to search for anything. Also I've noticed that searches come back as ManagedObjectReferences and can't be cast to the subclasses. You have to construct them passing the ManagedObjectReference as an argument.
Also I find searching for PowerCLI examples and watching the classes in the immeadiate window very help in navigating this API. It's a fairly decent SDK but they put all of the classes in a single namespace and there's lots of little style inconsistencies ( Device instead of Devices and properties that take strings instead of enums when an enum exists ).
i figured out how to do it :) , by using http://vcenter_hostname/mob I was able to walk through api better. here is what I did, plus instead of of using "host" which was type HostSystem I jused my instance of my vCenter host "client"
VMware.Vim.LicenseManager lic_manager = (VMware.Vim.LicenseManager)client.GetView(client.ServiceContent.LicenseManager, null);
LicenseManagerLicenseInfo[] lic_found = lic_manager.Licenses;
foreach (LicenseManagerLicenseInfo lic in lic_found)
{
string test = lic.Name.ToString();
string test2 = lic.LicenseKey.ToString();
}

FOP and IKVM in .NET - Images Not Working

UPDATE2: I got it working completely now! Scroll way down to find out how...
UPDATE: I got it working! Well... partially. Scroll down for the answer...
I'm trying to get my FO file to show an external image upon transforming it to PDF (or RTF for that matter, but I'm not sure whether RTFs are even capable of displaying images (they are)) with FOP, but I can't seem to get it working. (The question asked here is different than mine.)
I am using IKVM 0.46.0.1 and have compiled a FOP 1.0 dll to put in .NET; this code worked fine when I didn't try to add images:
private void convertFoByMimetype(java.io.File fo, java.io.File outfile, string mimetype)
{
OutputStream output = null;
try
{
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
// configure foUserAgent as desired
// Setup outputput stream. Note: Using BufferedOutputStream
// for performance reasons (helpful with FileOutputStreams).
output = new FileOutputStream(outfile);
output = new BufferedOutputStream(output);
// Construct fop with desired output format
Fop fop = fopFactory.newFop(mimetype, foUserAgent, output);
// Setup JAXP using identity transformer
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(); // identity transformer
// Setup input stream
Source src = new StreamSource(fo);
// Resulting SAX events (the generated FO) must be piped through to FOP
Result res = new SAXResult(fop.getDefaultHandler());
// Start XSLT transformation and FOP processing
transformer.transform(src, res);
}
catch (Exception ex)
...
}
However, when I (or rather a DocBook2FO transformation) added the following code:
<fo:external-graphic src="url(images/interface.png)" width="auto" height="auto" content-width="auto" content-height="auto" content-type="content-type:image/png"></fo:external-graphic>
into the FO file, the image did not show. I read through a bit of the FAQ on Apache's site, which says:
3.3. Why is my graphic not rendered?
Most commonly, the external file is not being found by FOP. Check the
following:
Empty or wrong baseDir setting.
Spelling errors in the file name (including using the wrong case).
...
Other options did not seem to be my case (mainly for the reason below - "The Weird Part"). I tried this:
...
try
{
fopFactory.setBaseURL(fo.getParent());
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
foUserAgent.setBaseURL(fo.getParent());
FOURIResolver fourir = fopFactory.getFOURIResolver();
foUserAgent.setURIResolver(fourir);
// configure foUserAgent as desired
...
with no avail.
The Weird Part
When I use the command-line implementation of FOP, it works fine and displays my image with no problem. (I don't want to go the run-command-line-from-program route, because I don't want to force the users to install Java AND the .NET framework when they want to use my program.)
The png file is generated from GDI+ from within my application (using Bitmap.Save). I also tried different png files, but none of them worked for me.
Is there anything I might be missing?
Thanks a bunch for getting this far
UPDATE and possible answer
So I might have figured out why it didn't work. I put some time into studying the code (before I basically just copypasted it without thinking about it much). The problem is indeed in the wrong basedir setting.
The key is in this chunk of code:
// Setup JAXP using identity transformer
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(); // identity transformer
// Setup input stream
Source src = new StreamSource(fo);
// Resulting SAX events (the generated FO) must be piped through to FOP
Result res = new SAXResult(fop.getDefaultHandler());
// Start XSLT transformation and FOP processing
transformer.transform(src, res);
What happens here is an identity transformation, which routes its own result into an instance of FOP I've created before. This effectively changes the basedir of the routed FO into that of the application's executable. I have yet to figure out how to do this without a transformation and route my input directly into FOP, but for the moment I worked around this by copying my images into the executable's directory.
Which is where another problem came in. Now whenever I try to execute the code, I get an exception at the line that says transformer.transform(src, res);, which confuses the pants out of me, because it doesn't say anything. The ExceptionHelper says:
java.lang.ExceptionInInitializerError was caught
and there is no inner exception or exception message. I know this is hard to debug just from what I wrote, but I'm hoping there might be an easy fix.
Also, this e-mail seems vaguely related but there is no answer to it.
UPDATE2
Finally, after a few sleepless nights, I managed to get it working with one of the simplest ways possible.
I updated IKVM, compiled fop with the new version and replaced the IKVM references with the new dlls. The error no longer occurs and my image renders fine.
I hope this helps someone someday
I'm using very similar code, although without the FOUserAgent, Resolvers, etc. and it works perfectly.
Did you try setting the src attribute in the XSLT without the url() function?
What might help you diagnose the problem further are the following statements:
java.lang.System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog")
java.lang.System.setErr(New java.io.PrintStream(New TraceStream(TraceStream.Level.Error)))
java.lang.System.setOut(New java.io.PrintStream(New TraceStream(TraceStream.Level.Info)))
Where TraceStream is a .NET implementation of a java.io.OutputStream which writes to your favorite logger.
I posted a version for the Common.Logging package at http://pastebin.com/XH1Wg7jn.
Here's a post not to leave the question unanswered, see "Update 1" and "Update 2" in the original post for the solution.

C# / Postgres / FluentNHibernate : configuring npgsql throws NotSupportedException

Sometimes I really start wondering what's going on in my sourcecode:
I'm trying to connect to PostGres 9.0 using npgsql 2.0.11.0, which I'm damn sure I already did, but right now, my program throws a NotSupportedException as it steps into the following :
ISessionFactory sf = Fluently.Configure()
.Database(PostgreSQLConfiguration.PostgreSQL82
.ConnectionString(c => c
.Host("localhost")
.Port(5432)
.Database("cw")
.Username("cw")
.Password("mypass")))
.Mappings(x => x.FluentMappings.AddFromAssemblyOf<MyMapping>())
.BuildSessionFactory();
The Stacktrace is quite neat to look at: Just one line.
at NHibernate.Dialect.Dialect.GetDataBaseSchema(DbConnection connection) in d:\CSharp\NH\nhibernate\src\NHibernate\Dialect\Dialect.cs:Line 718.
I tried transcribing this to the following:
ISessionFactory sf = Fluently.Configure()
.Database(PostgreSQLConfiguration.PostgreSQL82
.ConnectionString(c => c.Is("Server=localhost;Port=5432;Database=cw;User Id=cw;Password=myPass;")))
.Mappings(x => x.FluentMappings.AddFromAssemblyOf<CardTemplateMapping>())
.BuildSessionFactory();
Still, the result's the same. Anybody had similar issues or - even better - a fix?
I guess I'll end up holding a record for the most self-answered questions.
It needed the hbm2ddl.keywords property set to none. Now it works like a charm.
Cheers!
.Database(PostgreSQLConfiguration.PostgreSQL82
.Raw("hbm2ddl.keywords","none"));
See that you already found a solution. So just for some background:
The "none" will disable any operation regarding RDBMS KeyWords.
And the Keywords is available for MsSQL, Oracle, Firebird, MsSqlCe, MySQL, SQLite, SybaseAnywhere.
Since Postgress is not in the list it has to be set to None.
There is som info on it here: Quoting column names with NHibernate and PostgreSQL

Changing values in Web.config with a Batch file or in .NET code

I have a web.config file on my computer.
There are alot of things i need to change and add in the file.
(I am actually working with my SharePoint web.config file)
Can i do this with a Batch file, if so how would i do it.
Or how would i do it using VB.NET or C# code?
Any ideas guys?
Edit: i need to create a program to alter a web.config of lets say i web.config laying on my deskop and not the actual web.config of my project
Regards
Etienne
You can modify it from C# code, for example:
Configuration configuration = WebConfigurationManager.OpenWebConfiguration("~");
AppSettingsSection appSettingsSection = (AppSettingsSection)configuration.GetSection("appSettings");
if (appSettingsSection != null)
{
appSettingsSection.Settings["foo"].Value = "bar";
config.Save();
}
where foo is the key and bar the value of the key to set, obviously. To remove a value, use Settings.Remove(key);
See the msdn documentation for more information about the OpenWebConfiguration method and more.
The context in which you want to change the file really affects how you should do it. If you're looking at performing changes relatively frequently, but in an administrative domain, then some sort of command-line tool makes sense, and in this case I'd agree with JaredPar that PowerShell would be a valuable tool.
If, on the other hand, you find yourself in a situation where you need to modify the web.config in a more programmatic environment (e.g., as part of a setup program), then using programmatic technologies might make more sense. I recently had to do such a thing and Linq to Xml proved very convenient.
For example, to open a document "C:\foo\bar.xml" you could do something like (untested, no convenient build environment at the moment):
XDocument config = XDocument.Load(#"C:\foo\bar.xml");
You could then carry on in the usual fashion with the API. Note that this may be overkill if you're doing an administrative task as opposed to a programmatic task-- there are big, long-term advantages to learning a tool like PowerShell.
Finally, if you're modifying the web.config from within the program that the web.config is being used for, and you aren't doing anything too fancy or dynamic, then using the built-in Settings or ConfigurationManager may be the way to go.
Your best bet might to change it using a MSBuild Script and the MsBuild Community Tasks XML Mass update task
I would personally recommend using PowerShell. This is the next gen command line from Microsoft and it's sits right on top of .Net. It was built to do items like batch edits across large sets of files.
For a change in web.config in a SharePoint environment you have classes specially developed for this task. You only have to search for SPWebConfigModification class.
To load an arbitrary .NET config file
string configLocation = #"C:\myconfigFile.Config";
ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap();
configFileName = configLocation;
configFileMap.ExeConfigFilename = configFileName;
Configuration configuration= ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);
Then use Razzie's code to alter the actual config setting
AppSettingsSection appSettingsSection = (AppSettingsSection)configuration.GetSection("appSettings");
if (appSettingsSection != null)
{
appSettingsSection.Settings["foo"].Value = "bar";
configuration.Save();
}
This is what i needed to do.......thanks for all the help!!!
// Read in Xml-file
XmlDocument doc = new XmlDocument();
doc.Load("C:/Web.config");
//SaveControl tag..........................................................
XmlNode n = doc.SelectSingleNode("/configuration/SharePoint/SafeControls");
XmlElement elemWeb = doc.CreateElement("SafeControl");
elemWeb.SetAttribute("Assembly", "SamrasWebOption4");
elemWeb.SetAttribute("Namespace", "SamrasWebOption4");
elemWeb.SetAttribute("TypeName", "*");
elemWeb.SetAttribute("Safe", "True");
XmlElement elemSmartPart = doc.CreateElement("SafeControl");
elemSmartPart.SetAttribute("Assembly", "Machine_Totals");
elemSmartPart.SetAttribute("Namespace", "Machine_Totals");
elemSmartPart.SetAttribute("TypeName", "*");
elemSmartPart.SetAttribute("Safe", "True");
//Appending the Nodes......................................................
n.AppendChild(elemWeb);
n.AppendChild(elemSmartPart);
//Saving the document......................................................
doc.Save("C:/Web.config");

Categories