Wednesday, December 19, 2012

SaveOrUpdate Vs Update and Save in NHibernate

Chapter 9 :

http://www.nhforge.org/doc/nh/en/index.html

But cliff notes:

Save() takes a new object without an identifier and attaches it to the session. The object will beINSERT'd.

Update() takes an existing object that has an identifier but is not in the session and attaches it to the session. The object will be UPDATE'd.

SaveOrUpdate() looks at the identifier and decides what is necessary in the above.

SaveOrUpdateCopy() is special in that say you have two objects with the same identifier -- one in the session and one not. If you try and update the one not in the session an exception is thrown normally (you are now trying to attach two objects that represent the same persistent object to the session).SaveOrUpdateCopy() copies the non-session object state to the session object state.

I'm not sure how you are going to use NH, but for a lot of cases all you need is Save(). The session is doing ALL of the work necessary to know what has to be updated and simply Flush() or a Commit()does everything you need.

You usually don't need SaveOrUpdate() because NHibernate tracks changes to every loaded object. To update an object use Session.Get(), make you change then call Session.Flush()

NHibernate defaults

Nullable – yes, all properties are nullable by default
Lazy – yes, all properties are lazy by default. They must be virtual and public or protected.
Cascade – default is None
Inverse - default is false, meaning this side is maintaining the relationship

NHibernate Get vs Load behavior in whether returning the proxy or not

When returning an entity by using Get or Load, NHibernate first tries to return it from the session cache.
If it’s not there, then Get and Load will return the entity in a different way.
When calling Get, NHibernate will perform a roundtrip to database and return the non-proxy entity object or null in case the record does not exist:
var user = session.Get<User>(122);
For Load, NHibernate will return a proxy of the entity object or throw an exception if the record does not exist:
var user = session.Load<User>(122);
Suppose we have the following calls:
var a = session.Load<Assignment>(1);
var b = session.Get<Assignment>(1);
Note that in the 2nd case, b is a proxy and not the entity because the entity proxy exists in the session cache due to the Load call.
var a = session.Get<Assignment>(1);
var b = session.Load<Assignment>(1);
In this case b is a non-proxy entity object, due to the Get call.

Friday, November 16, 2012

Remote debugging in Visual Studio, target on a different domain

My computer is a Windows 7 32bits and I had to debug a ASP.NET 32 bit worker process running on a Windows Server 2008 64 bit machine.

The server is in a VPN and in a domain.

What I did was, on the server, I first ran this tool:

Start\Programs\Microsoft Visual Studio 2010\Visual Studio 2010 Remote Debugger (x86)

Make sure your user has permissions to debug the apps, so you can go to Tools\Options and click on Permissions. Your user should have Debug permission.

The tool says “Msvmon started  a new server  named ‘JohnDoe@VMXXXXXX. Waiting for connections’.

Now, in Visual Studio 2010 on my machine, I went to “Debug\Attach to Process” and in Qualifier, I put JohnDoe@XX.XX.XX.XX where XX.XX.XX.XX is the IP of the server. Note that I didn’t use the ‘JohnDoe@VMXXXXXX’. It didn’t work for me.

Two things worth mentioning:

1. you need to have the same user and password on the local machine. I created a separate account on my machine for this.

2. you cannot debug 64 bit processes from a 32 bit machine. Luckily, my processes were running as 32 bit processes so I could debug them.

HibernateException: Creating a proxy instance failed –> Unable to obtain public key for StrongNameKeyPair issue

I stumbled upon the following exception for a webapp of a particular site:

HibernateException: Creating a proxy instance failed –> Unable to obtain public key for StrongNameKeyPair.

Strange thing because this was only for one site, the other sites which have the same code didn’t have this issue.

This link gave me a good start:

http://stackoverflow.com/questions/5659740/unable-to-obtain-public-key-for-strongnamekeypair

“NHibernate is dynamically creating .NET assemblies (dynaic proxies) and needs to sign them. By default the Windows OS configures the crypto key storage to be machine level and stores the keys in C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys. Most likely your user can create (for example) a text file in this folder, but not delete it because you do not have full control.”

After reading this, what I did was I went to IIS Manager and checked the identity for the app pool which was running the webapp.

It was set to ApplicationPoolIdentity which creates a virtual account with the name of the new application pool and run the Application Pool's worker processes under this account:

http://forums.iis.net/t/1173831.aspx

Setting the identity to NetworkService made the app work fine like in other sites.

Sunday, October 30, 2011

Merged Dictionaries with ResourceDictionary set to linked XAML

As you know, you can add a linked XAML file using "Add as link" feature from "Add file" in Visual studio.

I created a folder in the project called 'HistogramControl' and then added different .cs and Histogram.xaml file as links.

Here is how app.xaml looks like:


For some reason it didn't initially work, I was getting 'invalid malformed' exception error when running the app. It looked like it didn't like the URI of the Source.

I closed VStudio, deleted bin and obj directories, and rebuilt. It worked!

Sunday, June 12, 2011

Set focus to Silverlight application and to a scrollviewer content

First, when the webbrowser is displaying the Silverlight app, the HTML element of the Silverlight plugin(object tag) might not have the focus.

This is independent of the Silverlight focus.

I've written a simple test Silverlight application which starts a DispatcherTimer and outputs in the debug output the currently focused element:

The MainPage xaml:
Background="White">

The code behind:
public partial class MainPage : UserControl
{
DispatcherTimer t = new DispatcherTimer()
{
Interval = new TimeSpan(0, 0, 1)
};
public MainPage()
{
InitializeComponent();
t.Tick += new EventHandler(t_Tick);
t.Start();
}

void t_Tick(object sender, EventArgs e)
{
object elem = FocusManager.GetFocusedElement();
if (elem == null)
{
Debug.WriteLine("Reported focused element is null");
}
else
{
Debug.WriteLine(elem);
}
}
}

The "Reported focused element is null" is written to debug output.

Using this method we can see which element has focus in the application and try to fix it.

What I did next is to set the focus in the Loaded event:

public MainPage()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
t.Tick += new EventHandler(t_Tick);
t.Start();
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
this.Focus();
}

This makes it to report that MyControl has the focus.

Note that if we would remove MyControl it will says that no control has focus, even if we focus to the main page control.
That's because there is no control in the MainPage which can have the focus. All focusable elements are the ones deriving from Control class.

Also, if we keep MyControl but remove the this.Focus() call from Loaded, it will still report that no control has focus.

Now, having MyControl and this.Focus() call set, we still cant process any key press on the MyControl.
That's because the focus is not set to the HTML Element of the Silverlight plugin (the object tag).
This also shows that focus in Silverlight is different then the real focus in HTML page, between the HTML elements of the page.
What's interesting is that we can process the key press in the main page control.
So even if the FocusManager reports null, the key press events can be process on the main page control.

In order to set focus on the Silverlight app, we have two options.
#1 We can make it from the HTML:


Make sure the object tag has id set:


#2. Make it from app code:

void MainPage_Loaded(object sender, RoutedEventArgs e)
{
HtmlPage.Plugin.Focus();
}

Now we can process the keys in the MyControl control.
We don't need to call this.Focus() anymore.

What I wanted next is to put the MyControl in a ScrollViewer

Background="White">

Without IsTabStop the focus goes to the ScrollViewer.
But with it, the reported focused element is null.
I changed the way focus is set by posting the call in the thread's message stack:

void MainPage_Loaded(object sender, RoutedEventArgs e)
{
Dispatcher.BeginInvoke(() =>
{
HtmlPage.Plugin.Focus();
});
}

This made it to work.
Without using BeingInvoke, it didn't work.