Fluent NHibernate Automap Joined Sub-Class Setting the Key - nhibernate

When automapping a joined subclass in fluent nhibernate, I can't figure out how to give the joined subclass a primary key.
public class Address:Entity {
public virtual string Address1 { get; set; }
public virtual string Address2 { get; set; }
public virtual string City { get; set; }
public virtual string State { get; set; }
public virtual string Zip { get; set; }
public virtual string Phone { get; set; }
public virtual string Fax { get; set; }
public virtual IList<Location> Locations { get; set; }
}
public class Location:Address {
public virtual Address BillingAddress { get; set; }
public virtual string OfficeHours { get; set; }
public virtual string PatientAgeRestrictions { get; set; }
public virtual bool WheelchairAccess { get; set; }
public virtual string ContactPerson { get; set; }
public virtual string ContactEmail { get; set; }
public virtual string ContactPhone { get; set; }
public virtual string ContactFax { get; set; }
public virtual string TaxId { get; set; }
}
I want Location to have it's own id "location_ id" with it's own sequence. Then I want that mapped to address through an address_id column.
Right now it's generating the location with "addressid" as the primary key, which isn't what I want. How do I change this with the automapping?

I'm not sure you have a joined-subclass relationship. That is, by definition a joined subclass has the same ID as its parent class. For example, you might have a Person entity stored in your database for generic "people" information like name/age/etc and then an Employee subclass entity which is stored in a different table and holds data like position, salary, and dates of employment. So an Employee is a subtype of Person and to get the full "Employee-Person" object, you must join the two tables on their primary keys (e.g. SELECT * FROM Employee INNER JOIN Person ON Employee.Employee_id = Person.Person_id).
Are you sure about your relational model here? Is Location truly a subtype of Address? Inferring a bit from your property names, it seems to me that this is not what you intend. It seems like you probably have a many-to-many between an Address and an Organization (that is, there may be many "organizations" at the same address and an "organization" may have many addresses), with a "contact person" for the organization at a specific address. In which case you should map "organization", "contact", and another entity that defines the relationship between Address and "organization".

Related

EntityFrameworkCore - Classes and Entity distinction

Just been writing up my models and dbcontext using a code first approach for EFCore and i've hit a small problem... specifically with classes and generating migrations.
It seems with entityframework any class is seen as an entity/table (my assumptions so far) but what if I want a class to be a list of fields extended onto my entity?
For example:
public class Person {
public int Id { get; set; }
public string Name { get; set; }
public Address AddressDetails { get; set; }
}
public class Address {
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string AddressLine3 { get; set; }
public string City { get; set; }
public string County { get; set; }
public string PostCode { get; set; }
}
How can I mark the address class as additional fields to the person entity as opposed to a separate entity?
Cheers,
Mark

ASP MVC 4 Mapping one to one relationship code first

I am new to ASP MVC and am working on a project with complex related data model. so while working on the relationships i looked online and got the following example on the Blog of asps.net :
namespace CodeFirst.Associations.OneToOneFK
{
public class User
{
public int UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int BillingAddressId { get; set; }
public int DeliveryAddressId { get; set; }
public Address BillingAddress { get; set; }
public Address DeliveryAddress { get; set; }
}
public class Address
{
public int AddressId { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string PostalCode { get; set; }
}
}
So my doubt is do we really need both the int BillingAddressID as well as Address BillingAddress?
Also, how do we associate an address to a user if we don't use AddressID.
Thanks for the help. :)
int BillingAddressID is called a foreign key property.
BillingAddress is called a navigation property (in this case a reference navigation property).
Foreign key properties aren't required to define a relationship, but they do simplify certain coding patterns. The general recommendation is to use both navigation properties and foreign key properties.
See here for more information about why FK associations were introduced.

How to create mapping relationship using Fluent NHibernate

How can I map one-to-many relationship with
User to Address,
Customer to Address,
Agency to Address and
store in a single Address Table using Fluent NHibernate
public class User
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual IList<Address> Address { get; set; }
}
public class Customer
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual IList<Address> Address { get; set; }
}
public class Agency
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual IList<Address> Address { get; set; }
}
public class Address
{
public virtual int Id { get; set; }
public virtual string Address1 { get; set; }
public virtual string Address2 { get; set; }
public virtual string City { get; set; }
public virtual string State { get; set; }
}
I think you'll need to store your relations independently to connect addresses and users/customers/agencies if you want to be able to use the same address for all types. This involves introducing a new table that only stores ID pairs, and making that the storage location for your relationship.
You can map collections as many-to-many and use the table method to name your link table. Your mapping would look something like:
public UserMap : ClassMap<User> {
Id (u => u.Id);
Map (u => u.Name);
HasManyToMany (u => u.Addresses).Table ("UsersXAddresses");
}
You'll need a similar link table for customers and agencies.
In the constructor for your mapping class, map the link using the HasMany method. HasMany will create a one-to-many relationship. HasManyToMany will create a many-to-many relationship.
For example: HasMany(x => x.Address).LazyLoad();
This will create a one-to-many relationship between the User class and the Address class.
For the many-to-many, you will also need to specify the table name and if you so desire, the left and right side table mappings.
For example: HasManyToMany(x => x.Address).Table("AddressToUser").ParentKeyColumn("AddressId").ChildKeyColumn("UserId").LazyLoad();
If you decide that you want to set up a distinction between a UserAddress and an AgencyAddress (where these are sub-classes of Address) - you can use the DiscriminateSubClassesOnColumn method in the AddressMap class so the FNH knows to create an extra column in order to determine which type of object to create.
For example: DiscriminateSubClassesOnColumn("Type").AlwaysSelectWithValue();
You should be able to use FNH Automapping to map these classes "as is".
It will handle all the relationships in your object model.
I believe it will put all the addresses in a single Address table as you desire, but can't say for sure.

Searching through child objects nhibernate search?

I have this kind of relationship
Supplier -> has many Products
Both Supplier is indexed and products are indexed. I need (boss wants to) search through both the Supplier and all of the suppliers' products and list the resulting suppliers.
Is this possible in nhibernate.search/Lucene.NET??
Yes it is possible : http://ayende.com/blog/3992/nhibernate-search
See the given example, IndexEmbedded attribute means the "child" object or collection will be indexed too :
[Indexed]
public class Post
{
[DocumentId]
public virtual int Id { get; set; }
[IndexedEmbedded]
public virtual Blog Blog { get; set; }
[IndexedEmbedded]
public virtual User User { get; set; }
[Field(Index.Tokenized, Store = Store.Yes)]
public virtual string Title { get; set; }
[Field(Index.Tokenized)]
public virtual string Text { get; set; }
public virtual DateTime PostedAt { get; set; }
public virtual ISet<Comment> Comments { get; set; }
[IndexedEmbedded]
public virtual ISet<Category> Categories { get; set; }
[IndexedEmbedded]
public virtual ISet<Tag> Tags { get; set; }
}

NHibernate - QBE

I have a problem using QBE with NHibernate. I have a one-to-one relationship between a Person class and an Employee.
public class Person
{
public virtual Employee Employee { get; set; }
public virtual int Age { get; set; }
public virtual string Forename { get; set; }
public virtual string Surname { get; set; }
public virtual int PersonID { get; set; }
}
public class Employee
{
public virtual int PersonID { get; set; }
public virtual string PayRollNo { get; set; }
public virtual int Holidays { get; set; }
public virtual Person Person { get; set; }
}
As an example, I want to get all Employees where Employee.Forename="John" and Employee.Person.PayRollNo = "231A". I was wondering if I could use Query By Example to do this?
I have not been able to find a definitive "no" but I haven't been able to get this work. I've found that QBE is promising but unfortunately not very useful due to the following limitations:
Cannot query related objects.
Requires public parameterless constructor.
Initialized properties are included in query unless specifically excluded using ExcludeProeprty. For example, bool properties are restricted to false in the where clause, DateTime as DateTime.MinValue. This makes the query very brittle because class modifications may have bad side effects.