I consider myself as a quite experienced user of Nhibernate, that is why I decided to check what is going on on the other side of barricade and started playing with Entity Framework. I followed the steps of some tutorial and I stuck at the very beginning of it. I was about to generate model classes using “Entity Data Model Wizard” but it turned out that the wizard could not find my SQL server (despite the fact that server itself was up and running).
I remember having similar issue a while back, but at that time I wasn’t able to solve it (I ended up creating connections string manually). This time I wanted to give this issue a closer look. After a bit of digging I found the problem – the SQL server wasn’t broadcasting information about itself. In order to fix it and make the server visible to other computers and applications it is necessary to start SQL Server Browser service. To do that go to Start -> Run and type Services.msc
Then in newly opened window find SQL Server Browser service
Double click it and set up startup type to Automatic. You can also click Start button to make sure that service starts immediately
From now on SQL servers should be visible in “Entity Data Model Wizard”
MsSql
FluentNhibernate – mapowanie kolumn typu time
Witam
Ostatnio napotkałem na dość ciekawy wyjątek podczas wykonywania NHibernatowego inserta. W bazie danych mam prostą tabelę
Do takiej tabeli został stworzony model
1 2 3 4 5 6 7 8 9 10 |
namespace Model { public class Appointment { public virtual int Id { get; set; } public virtual string Name { get; set; } public virtual DateTime StartDate { get; set; } public virtual TimeSpan Duration { get; set; } } } |
oraz mapping
1 2 3 4 5 6 7 8 9 10 11 12 13 |
namespace Model.Mappings { public class AppointmentMapping : ClassMap<Appointment> { public AppointmentMapping() { Id(val => val.Id).GeneratedBy.Native(); Map(val => val.Name).Not.Nullable(); Map(val => val.StartDate).Not.Nullable(); Map(val => val.Duration).Not.Nullable(); } } } |
Niestety ku mojemu zaskoczeniu próbując zapisać do bazy obiekt typu Appointment dostałem następujący wyjątek
SqlException: Operand type clash: bigint is incompatible with time
Mówiąc szczerze wyjątek ten niewiele mi powiedział, zwłaszcza, że zapytanie wygenerowane przez NHibernata (przechwycone w NHibernateProfilerze) wyglądało jak najbardziej poprawnie. Jednakże zapytanie przechwycone przez SqlProfilera wyglądało w następujący sposób
1 2 3 4 5 6 7 8 |
exec sp_executesql N'INSERT INTO [Appointment] (Name,StartDate,Duration) VALUES (@p0,@p1,@p2); select SCOPE_IDENTITY()', N'@p0 nvarchar(4000), @p1 datetime, @p2 bigint', @p0=N'appoitnemt', @p1='2012-03-13 00:00:00', @p2=439320000000 |
Widać tutaj, że drugi parametr (@p2) został oznaczony jako bigint, a nie time (tak jak jest to oznaczone w bazie). Przyczyną takiego stanu rzeczy jest zły mapping. Z tego co wyczytałem, jeżeli chcemy aby poprawnie zmapować TimeSpana na kolumnę typu time, musimy zmodyfikować interesujący nas mapping na następujący.
1 |
Map(val => val.Duration).Not.Nullable().CustomType("TimeAsTimeSpan"); |
Mając taki mapping nasze zapytanie zostanie wygenerowane poprawnie i operacja insertu zakończy się powodzeniem