Domanda

I'm facing some issues trying to model my business logic using NHibernate Fluent mapping.

I've a entity model like this:

public class Request
{
    ...
    public virtual Response Response {get; set;}
}

public class Response
{
    ...
    public virtual Request Request {get; set;}
}

My Request entity should be able to exist without a Response entity, and vice versa my Response entity should be able to exist without a Request. Can this be mapped as a one-to-one mapping? I know that is seems wired that a Response can exist without a Request, but that could happen in my situation.

I have read the article I Think You Mean a Many-to-one, Sir, but I still think that a many-to-one mapping is not the right thing for me, as none of my entities should have a list of either Responses or Requests.

How should this situation be mapped?

EDIT 1

My Fluent map using the foreign key association from How to do a fluent nhibernate one to one mapping?:

public RequestMap()
{
    Id(x => x.Id).GeneratedBy.Guid();
    References(x => x.Response, "ResponseId").Unique().Cascade.All();
}

public ResponseMap()
{
    Id(x => x.Id).GeneratedBy.Guid();
    HasOne(x => x.Request).Cascade.All().PropertyRef(x => x.Response);
}

This seems to work in many situations, but when I try to add multiple Request entities without a reference to a Response entity, I get this error:

System.Data.SqlClient.SqlException : Violation of UNIQUE KEY constraint 'UQ__Request__346FA94719588CEC'. Cannot insert duplicate key in object 'dbo.Request'. The duplicate key value is (). The statement has been terminated.

EDIT 2

public RequestMap()
{
    Id(x => x.Id).GeneratedBy.Guid();
    HasOne(x => x.Response).Cascade.All().PropertyRef(x => x.Request);
}

public ResponseMap()
{
    Id(x => x.Id).GeneratedBy.Guid();
    References(x => x.Request, "RequestId").Cascade.All();
}

Using this mapping, the mapping between the objects is not persisted when doing request.Response = response;. Should I make this setter protected?

È stato utile?

Soluzione

The issue with your EDIT 1 comes from these facts:

  • The Request table does have a unique constraint over the column "ResponseId". I.e. each row must have different value
  • The Requests stored without reference to Response do have NULL instead of any value... all of them. And that breaks the above requirement to have each row unique

Solution in this case would be to remove the unique key on the DB level from the ResponseId column. Because this is what we need (Request without Response). I.e. few concurrent NULL values in ReponseId should be allowed.

But what is a bit confusing me, is the naming: Reponse/Request

It seems to me, that Request (from my web development experience) is the trigger, the first one. And if all goes ok, there is a Response sent back. Should not your mapping be inversed? That the Response table contains the RequestId?

I've seen this statement in the question:

My Request entity should be able to exist without a Response entity, and vice versa my Response entity should be able to exist without a Request

Well, so ... let's assume that: the Response can NOT live without the Request... then your mapping (but inversed) should work even with the Unique key constraing.

And what is even more important, then the pure one-to-one mapping will work, because these two can share the Primary key (generated by Request, consumed by Response)

Altri suggerimenti

I might have misunderstood the question, but this seems to require you to map one of the entities with "References" and the other one with ">Inversed< References".

Please have a look here How to do a fluent nhibernate one to one mapping?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top