Fluent NHibernate & one-to-one - fluent-nhibernate

For a (very) long time I've been looking for an example on how to correctly implement a one-to-one mapping with Fluent NHibernate.
Most resources I find say:
I think you mean a many-to-one
However no one actually gives an example on how to correctly implement the one-to-one relation.
So, could you give an one-to-one mapping example with Fluent NHibernate?
Note: I'm not interested in people saying "what's your model, you might actually need HasMany". No, thanks, I simply need a one-to-one example.
To be more precise, I know the syntax. That's the only thing I could find by searching by myself. What I'm looking for is a more complete example, including a ((very) simple) database setup, and the whole mapping, of all entities that participate in the relationship, which I think would have reasonable size for Stack Overflow.

I've solved my problem.
I've also written a somewhat detailed article on this problem, that you can find at: http://brunoreis.com/tech/fluent-nhibernate-hasone-how-implement-one-to-one-relationship/index.html
You will find a scenario in which we want a one-to-one relationship, the database schema as we would like it, the code of the model as it needs to be to meet NHibernate requirements, and the Fluent mapping that corresponds to the situation.

these are the two classes.
public class A
{
public virtual int Id {get;set;}
public virtual string P1 {get;set;}
public virtual string P2 {get;set;}
public virtual string P3 {get;set;}
public virtual B child { get; set; }
}
public class B
{
public virtual int Id {get;set;}
public virtual string P4 {get;set;}
public virtual string P5 {get;set;}
public virtual string P6 {get;set;}
public virtual A parent;
}
this should be added in the fluent configuration.
public AMap()
{
/* mapping for id and properties here */
HasOne(x => x.child)
.Cascade.All();
}
public BMap()
{
/* mapping for id and properties here */
References(x => x.parent)
.Unique();
}

This is the best example I've seen. Hopefully it meets your needs.

HasOne(x => x.Prop)

Related

Object mapper vs Object wrapper

I would appreciate a little help here...
Lets say that in an application we have a Data Layer and a Business Logic Layer. In the DAL we have the following entity:
public class Customer {
public string Name {get; set;}
public ICollection<Address> Addresses {get; set;}
}
public class Address {
public string Street {get; set;}
}
In the BLL we have the following POCOs:
public class CustomerDto {
public string Name {get; set;}
public ICollection<AddressDto> Addresses {get; set;}
}
public class AddressDto {
public string Street {get; set;}
}
The entities in the DAL are populated with a ligth-weight ORM and retrieve from the BLL using a repository. Ex:
public class CustomerInformationService {
private readonly ICustomerRepository _repository {get; set;}
public CustomerInformationService (ICustomerRepository repository)
{
_repository = repository;
}
public class CustomerDto Get(int id)
{
var customerEntity = _repository.Get(id);
var customerDto = /* SOME TRANSFORMATION HERE */
return customerDTO;
}
}
My questions is about the /* SOME TRANSFORMATION HERE */ part. There is a discussion in our team about how to do the "mapping".
One approach is to use a mapper either an automapper or a manual mapping.
The second approach is to use sort of like a wrapper around Entity and reference the DTO in order to save a copying operation between object. Something like this:
public class CustomerDto
{
private IEntity _customerEntity;
public IEntity CustomerEntity { get {return _customerEntity;}}
public CustomerDto(IEntity customerEntity)
{
_customerEntity = customerEntity;
}
public string Name
{
get { return _customerEntity.Name; }
}
public ICollection<Address> Addresses
{
get { return _customerEntity.Addresses; }
}
}
The second approach feels a little weird to me because _customerEntity.Addresses feels like a leak (_customerEntity's reference) between my DAL and my BLL but I am not sure.
Are there any advantages/disavantages of using one approach over the other one?
Additional info: We usually pull a max. of 1000 records at a time that would need to be transform between Entity and DTO.
You did not mentioned your "ligth-weight ORM". I will answer in two sections.
If you are using ORM that creates proxies
You should avoid exposing Entities outside certain boundary. ORMs like NHibernate/EF implement lazy loading based on proxies. If you expose Entities to application/UI layer, you will have little control over ORM behavior. This may lead to many unexpected issues and debugging will also very difficult.
Wrapping Entities in DTOs will gain nothing. You are accessing Entities anyway.
Using DTOs and mapping them with some mapper tool like AutoMapper is good solution here.
If you are using ORM that does not create proxies
Do NOT use DTOs, directly use your Entities. DTOs are useful and recommended here in many cases. But the example you given in question does not need DTOs at all.
In case you choose to use DTOs, wrapping Entities in DTOs does not make sense. If you want to use Entity anyway, why wrap it? Again, tool like AutoMapper could help.
Refer this question. It's bit different; I am asking Yes/No and you are asking How. But still it will help you.
I bet for the service layer approach. Basically because something that looks like a business object or domain object has nothing to do with DTOs.
And, indeed, you and your team should use AutoMapper instead of repeating the same code tons of times which will consist in setting some properties from A to B, A to C, C to B...

How to prevent Nhibernate from fetching derived class?

I am using Nhibernate and I have a problem when fetching a base class with multiple derived classes (each class mapping a different table). When I watch the request, Nhibernate joins on every derived tables which has a huge an impact on the performances...
Here is a simplified vision of my classes :
public class Animal{
public virtual int ID { get; set;}
public virtual string Name { get; set;}
}
public class Dog : Animal{
//others properties
}
public class Cat: Animal{
//others properties
}
public class Person{
public virtual int ID { get; set;}
public virtual IEnumerable<Animal> Animals { get; set;}
}
A person has a list of Animals and I just want their names. The example is not perfect and more it's more complicated (a banking program) but it reflect well my problematic.
I KNOW it can be done differently etc, but it is a legacy so I don't have a choice...
Thanks in advance.
IMO NHibernate will only joind tables which contain projected columns. define a query but do not return Person but project into a dto/anonymous class the properties you need
After all, I created a class AnimalBase which is inherited by Dog, Cat and so forth and a class Animal without any child (both having the interface IAnimal).
As in 95% of my request, I only need Animal, I reference this class in my other objects like Person.
Not perfect but I did not find anything better...
Thanks Firo for your help.

Writing computed properties with NHibernate

I'm using NHibernate 2.1.2 + Fluent NHibernate
I have a ContactInfo class and table. The Name column is encrypted in the database (SQL Server) using EncryptByPassphrase/DecryptByPassphrase.
The following are the relevant schema/class/mapping bits:
table ContactInfo(
int Id,
varbinary(108) Name)
public class ContactInfo
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
public class ContactInfoMap : ClassMap<ContactInfo>
{
public ContactInfoMap()
{
Id(x => x.Id);
Map(x => x.Name)
.Formula("Convert(nvarchar, DecryptByPassPhrase('passphrase', Name))");
}
}
Using the Formula approach as above, the values get read correctly from the database, but NHibernate doesn't try to insert/update the values when saving to the database (which makes sense).
The problem is that I would like to be able to write the Name value using the corresponding EncryptByPassPhrase function. I'm unsure if NHibernate supports this, and if it does, I haven't been able to find the correct words to search the documentation effectively for it.
So... how can I write this computed property back to the database with NHibernate?
Thanks in advance!
A property mapped to a formula is read-only.
A named query wrapped up in a ContactInfoNameUpdater service might be one way to solve the problem.

nHibernate mapping for entity to multiple different parent entities (eg Addres -> Firm, Addres -> Client)

Can someone help me with the best way to map the following situation in fluent nHibernate? The Address class is used in both Client and Company. How can I store it most efficient in SQL? And what should the mapping look like? I've thought about multiple options, but I'm not experienced enough with nHibernate for these situations:
use 1 address entity and 1 table and use a denominator column to distinguish between address for client and address for company -> how to implement this in nHibernate?
use 1 address entity and 2 tables (ClientAddresses and CompanyAddresses) --> but I can only define 1 table in the mapping of the class Address
use 2 address entities and 2 tables --> not so elegant
I've just stumbled upon this problem when I started implementing the company class and realized it also needed multiple addresses. Up till now I had a Address and Client class and had a one-to-many mapping between them. In the database the Address had an extra column called ClientId. But with introducing the Company class I'm stuck...
Any help would greatly be appreciated.
I'm currently working in the sharparch 1.5 framework, which uses automapping and my mapping files are like this:
public class AddressMap : IAutoMappingOverride<Address>
{
public void Override(AutoMapping<Address> mapping)
{
mapping.Table("addresses");
mapping.Id(x => x.Id, "AddressGuid")
.UnsavedValue(Guid.Empty)
.GeneratedBy.GuidComb();
mapping.References(x => x.Client, "ClientGuid");
}
}
Below some more code the illustrate the problem:
Address
public class Address
{
public virtual string StreetLine1 { get; set; }
public virtual string StreetLine2 { get; set; }
public virtual string PostalCode { get; set; }
public virtual string City { get; set; }
public virtual string Country { get; set; }
}
which has the following table:
tablename = addresses
fields= AddressGuid, StreetLine1, StreetLine2, PostalCode, City, Country
Client
public class Client
{
public IList<Address> Addresses {get;set;}
}
Company
public class Company
{
public IList<Address> Addresses {get;set;}
}
It looks like you can implement #1 with nHibernate's <any> mapping. Note that in this case you cannot specify foreign-key constraints.
an example of <any>
Fluent nHibernate syntax
You could model the relationships as a many-to-many: many companies to many addresses, and many clients to many addresses.
In both your Company and Client mappings:
mapping.HasManyToMany(x => x.Addresses);
This will create two additional tables: one mapping between companies and addresses, another mapping between clients and addresses.
In theory this could allow sharing situations (some companies and clients all sharing have the same address row) which you probably don't want, but as long as your application logic doesn't allow that to happen, you'll be fine and you won't have to do anything tricky with nhibernate.

Mapping a dictionary in Fluent Nhibernate through a secondary key

I have a legacy DB which uses a guid to map children to the parent entity.
In my domain layer, I'd prefer to obscure this quirk, so I'd like to have my parent entity look like this:
public class Parent
{
virtual public int Id {get; protected set; }
virtual public string ParentContent { get; set; }
virtual public Guid ReferenceId { get; set; }
virtual public IDictionary<int,Child> Children { get; set; }
}
public class Child
{
virtual public int Id { get; protected set; }
virtual public Parent { get; set; }
virtual public string ChildContent { get; set; }
}
The parent would then map each Child.Id to Child in the Children dictionary. The Child mapping works fine, but I can't seem to find a reasonable mapping for the parent.
A field named ParentReferenceID exists in both Parent and Child tables, so I've attempted to map this with something like this:
mapping.HasMany<Broker>(x => x.Children)
.Table("Child")
.KeyColumn("ParentReferenceID")
.Inverse()
.AsMap<long>(index=>index.Id,val=>val.Type<Broker>());
Unfortunately, this produces an error:
The type or method has 2 generic parameter(s), but 1 generic argument(s) were provided. A generic argument must be provided for each generic parameter.
To simplify my problem, I started by trying Bag semantics, replacing the Parent's IDictionary with an IList. This was mapped using something like:
mapping.HasMany<Broker>(x => x.Brokers)
.Table("Child")
.KeyColumn("ParentReferenceId")
.Inverse()
.AsBag();
That produces the more obvious exception,
System.Data.SqlClient.SqlException: Operand type clash: uniqueidentifier is incompatible with int
Unfortunately, I can't seem to figure out the right way to tell it to join on the ReferenceID field. What's the right way to do that? I'd prefer the dictionary, but I'd be reasonably happy if I could even get the bag to work.
For clarity, I'm using a build of Fluent that is bundled with a recent SharpArchitecture pulled from git. The Fluent dll is marked version 1.0.0.594, but if a more recent build would help, I'm flexible.
Further digging has led me to a solution for the Bag case, though the dictionary is still giving me a bit of trouble.
The solution requires a patch to Fluent NHibernate's OneToManyPart mapping class. (Hat tip to This bug report: Could not map a one-to-many relationship where the key is not the primary key.
mapping.HasMany(x => x.Children)
.Table("Child").KeyColumn("ParentReferenceId")
.PropertyRef("ReferenceId")
.Inverse()
.AsBag();
Theoretically, AsMap should work almost the same way, but for some reason that I'm not entirely clear on, it doesn't work for me. I'll explore that later, but I'm open to suggestions.