one to one mapping in nhibernate

2019-08-05 10:54发布

问题:

I am using nhibernate. My code is as below

public class Store
    {
        public virtual int Id { get; protected set; }
        public virtual string Name { get; set; }
        public virtual IList<Employee> Staff { get; set; }

        public Store()
        {
            Staff = new List<Employee>();
        }
    }

Employee class

    public class Employee
        {
            public virtual int Id { get; protected set; }
            public virtual string FirstName { get; set; }
            public virtual string LastName { get; set; }
            public virtual Store Store { get; set; }
        }

storemap

    public class StoreMap:ClassMap<Store>
        {
            public StoreMap() 
            {
                Id(x => x.Id);
                Map(x => x.Name);
                HasMany(x => x.Staff).WithKeyColumn("store");
              }
        }

employeemap

public EmployeeMap ()
        {
            Id(x => x.Id);
            Map(x => x.FirstName);
            Map(x => x.LastName);
            References(x => x.Store  ).WithColumns("store");
        }

this is working fine. but i want one to one relation between employee and store and for that i try this but this doesn't work. in employeemap References(x => x.Store).WithForeignKey("store"); and in stormap

HasOne(x => x.Staff).WithForeignKey("store");

but this result in following error

persistent class not known:

 System.Collections.Generic.IList`1[[test.Models.Employee, test,
 Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]

Please help

回答1:

The one-to-one mapping is very specific. It says, that one object cannat exist without the other. Check docs 5.1.11. one-to-one and this for fluent How to do a fluent nhibernate one to one mapping?.

We can make it as an example liek this:

public StoreMap()
{
    Id(x => x.Id);
    HasOne(x => x.Staff).Cascade.All();
}

public EmployeeMap()
{
    Id(x => x.Id).GeneratedBy.Foreign("Store");
    HasOne(x => x.Store).Constrained();
}

Where is the Problem? Now we would have the Store which can live alone. That's ok. But any Employee will require a Store to be assigned to. And what is more important... the Employee won't have its own ID column. It will be in fact the column which could be nameed "StoreId", because the ID value would come from the Store.ID

suggestion

This scenario is very rare. And in fact, the mapping you already have seems to me pretty good.

I guess that you are trying to limit the amount of Staff assigned to the Store. This could be reasonable, and we can achieve that on the Buisness layer.

A clear (simplified) example could be something like this:

public class Store
{
    ...
    // not public
    protected virtual IList<Employee> Staff { get; set; }
    // here we do the trick on top of the mapping/hidden persistence layer
    public virtual Employee Employee 
    { 
       get { return Staff.FirstOrDefault(); }
       set { Staff[0] = value ; }


回答2:

A list virtual IList<Employee> Staff cannot map to HasOne

Simply make it not to be a list should work ;)