Thursday, August 21, 2014

Entity Framework 6 Migration: Could not load file or assembly

If this error finds you while doing EntityFramework migration my experience may help.

I have a solution like this:

ExampleSolution
   -   Example.Data
   -   Example.Web


The DbContext resides in my Example.Data project and the Example.Web is the startup project that feeds the connection string. Example.Web has a reference of Example.Data.

The thing that actually triggers the error is that I override the Seed method to seed some Roles and Users for my application. I also used custom Membership and Role provider configured with Web.config.

So when I run Update-Database command it fails with:
Could not load file or assembly Example.Web, Version=1.0.0.0, Culture=neutral' or one of its dependencies.
The system cannot find the file specified.

Here is what I have in the seed method:

protected override void Seed(MyDbContext context)
{
    if (!Roles.RoleExists("Admin")) Roles.CreateRole("Admin");
}

This code needs the Role provider. But the provider classes are placed in Example.Web project. So when the migration take places the Example.Web assemble is not present in the output folder of Example.Data. That causes the file not found exception. If I manually copy the assemblies of Example.Web to Example.Data's output folder, it solves the problem.

The real fix for this problem however is to use AppDomainBaseDirectory switch with Update-Database command and provide the full path of the bin directory of Example.Web like:

Update-Database -Verbose -Force -AppDomainBaseDirectory "C:\Path\To\bin"

As the Example.Web has a reference to Example.Data, all the required assemblies will be in Example.Web's output folder.

By the way, the problem appeared after I migrated from EF5 to EF6.1. Somehow EF5 did the right thing for me so far.

Sunday, May 18, 2014

Sublime Text 2: Change background and foreground color of the terminal (Terminal Plugin)

I use "Terminal" plugin for Sublime Text 2. Now, when I open the Powershell with the "Open Terminal Here..." command I get this weird color combination.
Needless to say I don't like it. I like the default version.



So to "fix" it: 
1) Go to Preferences > Browse Packages..
2) Find the "Terminal" folder and open it.
3) Find "PS.ps1" file and open it.

You will get something like this:




Last two lines are responsible for the back and foreground color. Change the colors as you like, save it and be happy!

Saturday, January 29, 2011

Nhibernate: Send update queries even when no change made.

Disclaimer:  The test shown here may not be the best practice.

In my last post I showed a bizarre behavior of Nhibernate. Here is what I wrote,

When we flush and commit an ISession in Nhibernate, it goes to database to flush all changes even if you just make nothing but some select queries.

It turns out, it is not Nhibernate behaving weird but I have managed to planchet a ghost in my code.

The statement is correct for the first part but Nhibernate does not have to go to database if you just do some select queries.

Fabio Maulo himself addressed this issue in one of his blog posts “How Test your mappings: the Ghostbuster” 

After reading his post and a Stackoverflow Q/AI have managed to find out the problem.

Here is the mapping file of DineInTable class:

<class name="DineInTable">
    <property access="property" type="int" name="DisplayIndex"/>
    <property access="property" type="int" name="MaxGuest"/>
    <property access="property" type="int" name="TableState"/>
    <property access="property" type="bool" name="Smoking"/>
</class>

And the class definition:

    public class DineInTable
    {
        public virtual int DisplayIndex { getset; }
        public virtual int MaxGuest { getset; }
        public virtual int TableState { getset; }
        public virtual bool Smoking { getset; }
    }

As you can see in the mapping file all these properties are nullable but in the class definition they are not. I want to quote this Stackoverflow Answer which explains this very problem precisely.

The following sequence explains why this happens: 

1) Nhibernate retrieves raw entity's data from DB using ADO.NET
2) Nhibernate constructs the entity and sets its properties
3) If DB field contained NULL the property will be set to the defaul value for its type:
4) properties of reference types will be set to null
5) properties of integer and floating point types will be set to 0
6) properties of boolean type will be set to false
7) properties of DateTime type will be set to DateTime.MinValue  etc
Now, when transaction is committed, NHibernate compares the value of the property to the original field value it read form DB, and since the field contained NULL but the property contains a non-null value, NHibernate considers the property dirty, and forces an update of the enity.

So, that is exactly what is causing all those update queries. To fix the problem either I can make these properties Nullable in the class definition or can set not-null=true in the mapping file. In this case I do not want them to be null so went with not-null=true.

Here is the test again:
        [Test]
        private void CanGetDineInTableByGroup()
        {
           
            TableGroup tableGroup = this._dineInTableModel.GetTableGroupById(
                    new Guid("11111111-1111-1111-1111-111111111111"));
            var dineInTables = this._dineInTableModel.GetTablesByGroup(tableGroup);
            this._dineInTableModel.CloseConversation();

            Assert.IsNotNull(tableGroup);
            Assert.IsNotNull(dineInTables);           
          
        }

And the result:

CanGetDineInTableByGroup : Passed                                                      
*** ConsoleOutput ***
NHibernate: SELECT tablegroup0_.TableGroupId as TableGro1_0_0_, tablegroup0 …
NHibernate: select dineintabl0_.DineInTableId as DineInTa1_3_, dineintabl0  ….

Voila! Just two select queries as I expect.

Conclusion: 
Some very intelligent people wrote Nhibernate. In most cases you are the stupid one if you see something happing weird.  Kudos to TDD, without it, it would have been very difficult to find even this problem in the first place.

“Learning by test”


Wednesday, January 26, 2011

NHibernate.TransientObjectException: object references an unsaved transient instance

***Edit: please see the next post where i explained this behavior.

When we flush and commit an ISession in Nhibernate, it goes to database to flush all changes even if you just make nothing but some select queries***. Here is an experimental test case and its result:
        [Test]
        private void CanGetDineInTableByGroup()
        {           
            TableGroup tableGroup =      this._dineInTableModel.GetTableGroupById(
                    new Guid("11111111-1111-1111-1111-111111111111"));
var dineInTables = this._dineInTableModel.GetTablesByGroup(tableGroup);

            this._dineInTableModel.CloseConversation();

            Assert.IsNotNull(tableGroup);
            Assert.IsNotNull(dineInTables);           
           
        }

Here is the result:

*** ConsoleOutput ***
NHibernate: SELECT tablegroup0_.TableGroupId as TableGro1_0_0_, tablegroup0 …
NHibernate: select dineintabl0_.DineInTableId as DineInTa1_3_, dineintabl0 …

NHibernate: UPDATE DineInTable SET RowVer = @p0, DineInTableName, …
 NHibernate: UPDATE DineInTable SET RowVer = @p0, DineInTableName = @p1,…
NHibernate: UPDATE DineInTable SET RowVer = @p0, DineInTableName = @p1,… 
NHibernate: UPDATE DineInTable SET RowVer = @p0, DineInTableName = @p1,… 

I am using uNHAddins here. CloseConversation is a convenient method to call session.Flush() and transaction.Commit() entirely controlled by uNHAddins.

As you can see, there are four update queries.  Anyone knows why, please leave a comment.

Another important “gotcha “, after closing a conversation/flush & commit, if you try to execute query in a different Session with detached object of previous Session you will probably get an error like this:


        [Test]
        private void CanGetDineInTableByGroup()
        {
           
            TableGroup tableGroup = this._dineInTableModel.GetTableGroupById(
                    new Guid("11111111-1111-1111-1111-111111111111"));
var dineInTables = this._dineInTableModel.GetTablesByGroup(tableGroup);

            this._dineInTableModel.CloseConversation();

IList<DineInTable> tablesByGroup = this._dineInTableModel.GetTablesByGroup(tableGroup);
        
            Assert.IsNotNull(tablesByGroup);
            Assert.IsNotNull(tableGroup);
            Assert.IsNotNull(dineInTables);           
          
        }


CanGetDineInTableByGroup : Failed
*** Failures ***
Execute
NHibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing. Type: Xenon.XenonPOS.DomainModel.Entities.TableGroup, Entity: Xenon.XenonPOS.DomainModel.Entities.TableGroup


Here is what you need to make the test pass:

        [Test]
        private void CanGetDineInTableByGroup()
        {
           
            TableGroup tableGroup = this._dineInTableModel.GetTableGroupById(
                    new Guid("11111111-1111-1111-1111-111111111111"));
var dineInTables = this._dineInTableModel.GetTablesByGroup(tableGroup);

            this._dineInTableModel.CloseConversation();

            this._dineInTableModel.SaveOrUpdateTableGroup(tableGroup);

IList<DineInTable> tablesByGroup = this._dineInTableModel.GetTablesByGroup(tableGroup);
        
            Assert.IsNotNull(tablesByGroup);

            Assert.IsNotNull(tableGroup);
            Assert.IsNotNull(dineInTables);           
          
        }

SaveOrUpdateTableGroup() is actually opening a brand new ISession and attaching detached tableGroup to that session. Rest of the methods is sharing this same new Session.