Using Visual NUnit I can't debug the code and set breakpoints. So I wanted to attach the VS to the NUnit process, because then I can set the breakpoints and watch, what in variables I have.
But after attached to this process I couldn't look at the breakpoints, because I had no symbol loaded, so the brakepoints were disabled with info: "The brakepoint will not currently be hit. No symbols have been loaded for this document".
After some investigation, I found that, the tests and core projects must have the platform target property set to 'Any CPU' and the Attach to process must be set to nunit-agent.exe, not to nunit.exe. Now the symbols should work. If it doesn't, in debug mode we must go to Debug/Windows/Modules window, and there on the list, there should be out assemblies loaded. Pressing the right mouse button on each of our assemblies we have possibility to show, where on the disc the symbols (*.pdb files) are placed.
I decided today to go back and take another chance to NUnit, but firstly I needed to have a possibility to integrate the NUnit and VS, because launching external program to run my tests is tiring. After few minutes I fonud a nice VS plugin to integrate a Visual Studio and NUnit: it's name is Visual NUnit.
I had one problem with this extension. When I wanted to fire my first NUnit test, I had an System.BadImageFormatException exception. I had to change the tests project target platform to x86.
After checked the Visual NUnit I wanted to have a some snippets to create the basic NUnit structures without wasting my time to write it manually all the time. Fortunatelly I found it either: link.
After done mapping for my entities I wanted to test the basic CRUD operations. I stuck with a problem of inserting a data to tables in many to many relation, so I wanted to look at the generated sql by the NHibernate to find out, what is really generated to investigate the problem in my mappings. The NHibernate have a property called show-sql to show the generated statements.
I enabled it in the config:
var configure = new Configuration();
configure.SessionFactoryName("BuildIt");
configure.DataBaseIntegration(db =>
{
//...
db.LogFormattedSql = true;
db.LogSqlInConsole = true;
db.AutoCommentSql = true;
});
To set the output to the build-in console in Visual Studio I used a Maciej Aniserowicz solution.
His post is all in polish language, so a little clarification.
Every line of text send to System.Diagnostics.Debug.WriteLine(..) is going to the VS console. So Maciej added a simple wrapper for it:
public class CustomDebugWriter : TextWriter
{
public override void WriteLine(string value)
{
Debug.WriteLine(value);
base.WriteLine(value);
}
public override void Write(string value)
{
Debug.Write(value);
base.Write(value);
}
public override Encoding Encoding
{
get { return Encoding.UTF8; }
}
}
At the beginning of the application there must be placed a
#if DEBUG
Console.SetOut(new CustomDebugWriter());
#endif
to set the new class responsible for operating on the output set to the console.
Running that code results ALMOST in that way I wanted to. Generating sql is placed in the VS console, but only for sql SELECT statements and I didn't know why (really I still don't ;).
So I decided to use the log4net logging library to get the result in the file at least. After adding a reference to this library and set the framework target there must be done two things. One is placed in app.config/web.config the configuration for the library. I found somewhere a little config which work ok:
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
</configSections>
<log4net>
<appender name="NHibernateFileLog" type="log4net.Appender.FileAppender">
<file value="logs/nhibernate.txt"/>
<appendToFile value="false"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d{HH:mm:ss.fff} [%t] %-5p %c - %m%n"/>
</layout>
</appender>
<logger name="NHibernate.SQL" additivity="false">
<level value="DEBUG"/>
<appender-ref ref="NHibernateFileLog"/>
</logger>
</log4net>
And second is to add at the beginning of the application a single line
log4net.Config.XmlConfigurator.Configure();
In this moment we have all, including INSERT and UPDATE statements in the logs/nhibernate.txt file. But this is not all.
When we now check the VS console, we can see that we have there all the logs sended to the file, that means the INSERT/SELECT/UPDATE statements, so using this log file is useless :)
Don't know, why after added and configured the log4net library is started to work as I expected, but I'm glat it did :)
I just wanted to add a log4net library to log all the sql commands generated by NHibernate, but there was one problem.
After I downloaded this library using NuGet, I could add a code from this assembly to configure the library, intellisense worked as usual, but when I wanted to compile the project, I ended with error
The name 'log4net' does not exists in the current context
This was new experience to me, because I have never had that strange situation.
In every other solution that I created, this error existed.
Solution to this was to change in the project preferences the target framework from client to full version.
I think log4net have some dependencies to the stuff not available in the client version, like e.g. asp.net.
But I'm curious, why the compiler didn't show some more useful error message? WHY?
I'm diving in the NHibernate 3.2 mapping by code recently.
I throught that, mapping a string with specific max length to the appropriate database table will be easy, but it wasn't. I lost some time to figure it out.
At the beginning I mapped a string field in that way
Property<string>(x => x.Title, x => x.Length(Int32.MaxValue));
After generating the tables in database with my schema, unfortunatelly
this field was generated as a nvarchar(255) and I didn't know why.
We can deal with it in few ways.
1. We can manually set the length to the value greater than 4001 (link)
Property<string>(x => x.Title, x => x.Length(4002));
2. We can set the type in this way:
Property(x => x.Title, x => x.Type(NHibernateUtil.StringClob))
3. Or we can set manually the sql type:
Property<string>(x => x.Title, x => x.Column(z => z.SqlType("nvarchar(max)")));
I have today a little problem to parse in js a DateTime object, which I serialized to json in the acion method on the server by
return Json(messages);
In javascript, the date looks that: /Date(1309936900864)/
To parse the date in js I have used:
var parsedDate = new Date(parseInt(messages[i].CreatedDate.replace("/Date(", "").replace(")/",""), 10));