nhibernate connecting to legacy database - nhibernate

I am connecting to a legacy sqlserver database. One of the tables has column name "Primary". The scripts are failing due to that.
Script generated by nhibernate:
SELECT locations0_.CustomerID as CustomerID1_, locations0_.LocationID as LocationID1_, locations0_.LocationID as LocationID2_0_, locations0_.Primary as Primary2_0_,locations0_.CustomerID as CustomerID2_0_
FROM dbo.tblLocation locations0_
WHERE locations0_.CustomerID=?
Class:
public class Location
{
public virtual int LocationID { get; set; }
public virtual Customer Customer { get; set; }
public virtual int? CustomerID { get; set; }
public virtual string LocationName { get; set; }
public virtual string Address1 { get; set; }
public virtual string Address2 { get; set; }
public virtual string Address3 { get; set; }
public virtual string City { get; set; }
public virtual string StateOrProvince { get; set; }
public virtual string PostalCode { get; set; }
public virtual datetime? LTimeStamp{ get;set; }
public virtual bool Primary { get; set; }
}
Map:
public class TblLocationMap : ClassMap
{
public TblLocationMap()
{
Table("tblLocation");
//LazyLoad();
Id(x => x.LocationID).GeneratedBy.Identity().Column("LocationID");
References(x => x.Customer).Column("CustomerID");
Map(x => x.LocationName).Column("LocationName").Length(50);
Map(x => x.Address1).Column("Address1").Length(200);
Map(x => x.Address2).Column("Address2").Length(200);
Map(x => x.Address3).Column("Address3").Length(200);
Map(x => x.City).Column("City").Length(100);
Map(x => x.StateOrProvince).Column("StateOrProvince").Length(100);
Map(x => x.PostalCode).Column("PostalCode").Length(20);
//Map(x => x.Primary).Column("Primary").Not.Nullable();
//Map(x => x.LTimestamp).Column("LTimestamp");
HasMany(x => x.Contacts).KeyColumn("LocationID");
}
sql:
CREATE TABLE [dbo].[tblLocation]
(
[LocationID] [int] IDENTITY(1,1) NOT NULL,
[CustomerID] [int] NULL,
[LocationName] nvarchar NULL,
[Address1] nvarchar NULL,
[Address2] nvarchar NULL,
[Address3] nvarchar NULL,
[City] nvarchar NULL,
[StateOrProvince] nvarchar NULL,
[PostalCode] nvarchar NULL,
[Primary] [bit] NOT NULL,
[RecTimestamp] [timestamp] NULL,
(
[LocationID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
GenericADOException:
could not initialize a collection: [Domain.Locations#466][SQL: SELECT locations0_.CustomerID as CustomerID1_, locations0_.LocationID as LocationID1_, locations0_.LocationID as LocationID2_0_, locations0_.LocationName as Location2_2_0_, locations0_.Address1 as Address3_2_0_, locations0_.Address2 as Address4_2_0_, locations0_.Address3 as Address5_2_0_, locations0_.City as City2_0_, locations0_.StateOrProvince as StateOrP7_2_0_, locations0_.PostalCode as PostalCode2_0_, locations0_.Primary as Primary2_0_, locations0_.CustomerID as CustomerID2_0_ FROM dbo.tblLocation locations0_ WHERE locations0_.CustomerID=?]
Inner exception:
{"Incorrect syntax near the keyword 'Primary'."}

I suspect Primary is a reserved word and is not getting escaped properly, therefore try implicitly escaping the column name with back ticks....
e.g.
Map(x => x.Primary).Column("`Primary`").Not.Nullable();
NHibernate will automatically swap your backtick with square braces if you are using MsSql server [Primary]
Strange that the schema is generating square braces but the select SQL isn't.

Related

Store update, insert, or delete statement affected an unexpected number of rows (0) Tried context refresh already

I have tried various answers to try and get this fixed. I have tried to do a refresh but with no luck.
All my tables are currently empty. I already have #Html.HiddenFor~ in the view
My controller save action:
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize(Roles = "AdminManager")]
public ActionResult Save(Member member)
{
if (!ModelState.IsValid)
{
var viewModel = new MemberFormViewModel
{
Member = member,
Subjects = _context.Subjects.ToList()
};
return View("MemberForm", viewModel);
}
if (member.Id == 0)
_context.Members.Add(member);
else
{
var memberInDb = _context.Members.Single(m => m.Id == member.Id);
Mapper.Map(memberInDb, member);
}
_context.SaveChanges();
return RedirectToAction("Index", "Member");
}
Specifically the source error shown is:
_context.SaveChanges();
It seems that the code errors when adding a member:
_context.Members.Add(member);
Below is my table code:
CREATE TABLE [dbo].[Members] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Name] NVARCHAR (255) NOT NULL,
[DateOfBirth] DATETIME NULL,
[Gender] NVARCHAR (MAX) NULL,
[Email] NVARCHAR (MAX) NOT NULL,
[WorkLocation] NVARCHAR (MAX) NOT NULL,
[Address] NVARCHAR (255) NOT NULL,
[ContactNumber] NVARCHAR (MAX) NOT NULL,
[Biography] NVARCHAR (MAX) NULL,
[MoreInfo] NVARCHAR (MAX) NULL,
[SubjectId] INT NOT NULL,
[ReportId] INT NULL,
CONSTRAINT [PK_dbo.Members] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_dbo.Members_dbo.Reports_ReportId] FOREIGN KEY ([ReportId])
REFERENCES [dbo].[Reports] ([Id]),
CONSTRAINT [FK_dbo.Members_dbo.Subjects_SubjectId] FOREIGN KEY ([SubjectId])
REFERENCES [dbo].[Subjects] ([Id]) ON DELETE CASCADE
);
GO
CREATE NONCLUSTERED INDEX [IX_SubjectId]
ON [dbo].[Members]([SubjectId] ASC);
GO
CREATE NONCLUSTERED INDEX [IX_ReportId]
ON [dbo].[Members]([ReportId] ASC);
Here is my model that was used for the migration:
public class Member
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
[StringLength(255)]
public string Name { get; set; }
[Display(Name = "Date of birth")]
public DateTime? DateOfBirth { get; set; }
public string Gender { get; set; }
[Required]
public string Email { get; set; }
[Required]
[Display(Name = "Work Location")]
public string WorkLocation { get; set; }
[Required]
[StringLength(255)]
public string Address { get; set; }
[Required]
[Display(Name = "Contact Number")]
public string ContactNumber { get; set; }
public string Biography { get; set; }
[Display(Name = "More Information")]
public string MoreInfo { get; set; }
public Subject Subject { get; set; }
[Required]
[Display(Name = "Subject")]
public int SubjectId { get; set; }
public Report Report { get; set; }
[Key]
[ForeignKey("Report")]
[Display(Name = "Report")]
public int? ReportId { get; set; }
}

Not set "Discriminator" column when save entity in Entity Framework

I have a base class Person:
[KnownType(typeof(Doctor))]
public abstract class Person
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string Gender { get; set; }
public DateTime BirthDate { get; set; }
public string Email { get; set; }
public string MobilePhoneNumber { get; set; }
public string HomePhoneNumber { get; set; }
public bool IsGlobal { get; set; }
public bool IsDeleted { get; set; }
public bool IsApproved { get; set; }
public int? FacilityId { get; set; }
public int? AddressId { get; set; }
public virtual FacilityView Facility { get; set; }
public virtual Address Address { get; set; }
public virtual ICollection<Organization> Organizations { get; set; }
public virtual ICollection<TenantEntity> TenantEntities { get; set; }
}
And have nested class Doctor:
public class Doctor : Person
{
public string Speciality { get; set; }
}
Table Person script
CREATE TABLE [core].[Person](
[PersonId] [int] IDENTITY(1,1) NOT NULL,
[Discriminator] [nvarchar](255) NOT NULL,
[FirstName] [nvarchar](255) NOT NULL,
[MiddleName] [nvarchar](255) NULL,
[LastName] [nvarchar](20) NOT NULL,
[Gender] [nvarchar](20) NOT NULL,
[BirthDate] [date] NOT NULL,
[Email] [nvarchar](250) NULL,
[MobilePhoneNumber] [nvarchar](250) NULL,
[HomePhoneNumber] [nvarchar](250) NULL,
[IsGlobal] [bit] NOT NULL,
[IsDeleted] [bit] NOT NULL,
[IsApproved] [bit] NOT NULL,
[FacilityId] [int] NULL,
[AddressId] [int] NULL,
[Speciality] [nvarchar](250) NULL,
And when i try to save new Doctor entity i have an error:
Cannot insert the value NULL into column 'Discriminator'
What i do wrong in this situation?Why EF not save "Doctor" value in Discriminator field?
UPDATE:
part from DBContext:
public DbSet<Person> Persons { get; set; }
#region Person
modelBuilder.Entity<Person>()
.ToTable("Person", "core")
.HasKey(t => t.PersonId);
modelBuilder.Entity<Person>()
.HasOptional(t => t.Facility);
modelBuilder.Entity<Person>()
.HasOptional(t => t.Address);
modelBuilder.Entity<Person>()
.HasMany(x => x.Organizations)
.WithMany()
.Map(x =>
{
x.MapLeftKey("PersonId");
x.MapRightKey("OrganizationId");
x.ToTable("PersonOrganization", "core");
});
modelBuilder.Entity<Person>()
.HasMany(x => x.TenantEntities)
.WithMany()
.Map(x =>
{
x.MapLeftKey("PersonId");
x.MapRightKey("TenantEntityId");
x.ToTable("PersonTenantEntity", "core");
});
#endregion
The default inheritance mapping does not define a discriminator column if only one derived class exists.
Your code will work if you define a second class that derives from Person:
public class Nurse : Person
{
public string Whatever {get;set;}
}
Or add the discriminator explicitly to your model.
modelBuilder.Entity<Doctor>().Map(p => p.Requires("Discriminator").HasValue("Doctor"));

Fluent nhibernate map lookup table as enum

I am trying to map a lookup table to an enum using:
FluentNhibernate 1.3.0.733
NHibernate 3.3.1.4000
I am not able to load objects. If I remove the enum mapping I can load objects.
Code:
Order order = session.Get<Order>(id);
Error:
Provided id of the wrong type. Expected: Order+OrderStatus, got System.Int32
Object:
public class Order
{
public enum OrderStatus
{
PaymentPending = 0
}
public virtual int Id { get; set; }
public virtual Customer Customer { get; set; }
public virtual Address Address { get; set; }
public virtual IList<OrderLine> OrderLines { get; set; }
public virtual OrderStatus Status { get; set; }
public virtual DateTime Created { get; set; }
public Order()
{
OrderLines = new List<OrderLine>();
}
}
Mapping: (I have cut the mapping down to these fields for testing)
public OrderMapping()
{
Table("orders");
Id(x => x.Id);
Id(x => x.Status, "state_id").CustomType<Order.OrderStatus>().Not.Nullable();
References(x => x.Address).Cascade.All().Column("address_id");
References(x => x.Customer).Cascade.All().Column("customer_id");
}
Tables:
CREATE TABLE [order_states] (
[id] INTEGER NOT NULL PRIMARY KEY,
[state] NVARCHAR(50) NOT NULL
);
CREATE TABLE [orders] (
[id] INTEGER NOT NULL PRIMARY KEY,
[customer_id] INTEGER NOT NULL,
[address_id] INTEGER NOT NULL,
[state_id] INTEGER NOT NULL,
[created] DATE,
FOREIGN KEY(customer_id) REFERENCES customers(id),
FOREIGN KEY(address_id) REFERENCES addresses(id),
FOREIGN KEY(state_id) REFERENCES order_states(id)
);
What am I doing wrong?
Caused by a silly error.
I had the the status mapped as an id and not as a property.
Correct mapping:
public OrderMapping()
{
Table("orders");
Id(x => x.Id);
Map(x => x.Status, "state_id").CustomType<Order.OrderStatus>().Not.Nullable();
References(x => x.Address).Cascade.All().Column("address_id");
References(x => x.Customer).Cascade.All().Column("customer_id");
}

Fluent NHibernate Mapping for Table in multiple HasMany Relationships

What is wrong with my class mappings below?
public class Foo
{
public Foo()
{
ActualCurve = new List<Point>();
TargetCurve = new List<Point>();
}
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual IList<Point> ActualCurve { get; set; }
public virtual IList<Point> TargetCurve { get; set; }
}
public class Point
{
public virtual int Id { get; set; }
public virtual double X { get; set; }
public virtual double Y { get; set; }
}
public class FooMapping() : ClassMap<Foo>
{
Table("Foos");
Id(x => x.Id).GeneratedBy.Identity();
Map(x => x.Name).Not.Nullable();
HasMany(x => x.ActualCurve ).Cascade.All();
HasMany(x => x.TargetCurve ).Cascade.All();
}
public class PointMapping() : ClassMap<Point>
{
Table("Points");
Not.LazyLoad();
Id(x => x.Id).GeneratedBy.Identity();
Map(x => x.X).Not.Nullable();
Map(x => x.Y).Not.Nullable();
}
These mappings produce
CREATE TABLE [dbo].[Foos](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar] NOT NULL,
[RecipeRevisionId] [int] NOT NULL
CREATE TABLE [dbo].[Points](
[Id] [int] IDENTITY(1,1) NOT NULL,
[X] [float] NOT NULL,
[Y] [float] NOT NULL,
[FooId] [int] NOT NULL
Essentially, the problem is that when I am pulling a persisted Foo object back out of the database, the Foo.ActualCurve and Foo.TargetCurve lists both get populated with the combined contents of both lists. There clearly isn't a column that keys which set of points belong to the correct curve within Foo, but I am not sure how to change the mapping to maintain the two distinct sets of Points.
I think you will need to specify a separate column for the references:
HasMany(x => x.ActualCurve ).Cascade.All().KeyColumn("ActualCurveId");
HasMany(x => x.TargetCurve ).Cascade.All().KeyColumn("TargetCurveId");
EDIT: Column->KeyColumn

Fluent NHibernate Dictionary mapping problem

I have following entities
public class Entity1
{
public virtual Guid Id { get; set; }
public virtual IDictionary<Guid, Entity2> Entities2 { get; set; }
}
public class Entity2
{
public virtual Guid Id { get; set; }
public virtual IDictionary<Guid, Entity1> Entities1 { get; set; }
}
DB table
CREATE TABLE [dbo].[EntityLinks](
[Entity1Id] [uniqueidentifier] NOT NULL,
[Entity2Id] [uniqueidentifier] NOT NULL,
[LinkItemId] [uniqueidentifier] NOT NULL
)
and following mappings:
for Entity1
mapping.HasManyToMany<Entity2>(rc => rc.Entities2)
.Table("EntityLinks")
.ParentKeyColumn("Entity1Id")
.ChildKeyColumn("Entity2Id")
.AsMap<Guid>("LinkItemId")
for Entity2
mapping.HasManyToMany<Entity1>(rc => rc.Entities1)
.Table("EntityLinks")
.ParentKeyColumn("Entity2Id")
.ChildKeyColumn("Entity1Id")
.AsMap<Guid>("LinkItemId")
adding data works fine and I can get and see Entity1.Entities2 populated but Entity2.Entities1 is not populated.
Any suggestions why this might be?
Thank you in advance.
I'm probably wrong but you can try:
mapping.HasManyToMany<Entity2>(rc => rc.Entities2)
.Table("EntityLinks")
.ParentKeyColumn("Entity1Id")
.ChildKeyColumn("Entity2Id")
.AsMap<Guid>("LinkItemId")
.Inverse()
and
mapping.HasManyToMany<Entity1>(rc => rc.Entities1)
.Table("EntityLinks")
.ParentKeyColumn("Entity2Id")
.ChildKeyColumn("Entity1Id")
.AsMap<Guid>("LinkItemId")
.Cascade.All();