Question

I have the following two entities defined. A ResponseSeries can have a related TabletUserSession. It's a fairly straight forward one-to-zero-or-one relationship.

public class ResponseSeries : TrackedEntity
{
    public ResponseSeries()
    {
        Responses = new Collection<Response>();
    }
    public Int32 ResponseSeriesId { get; set; }

    public virtual TabletUserSession TabletUserSession { get; set; }
    public virtual ICollection<Response> Responses { get; set; }

}

and

public class TabletUserSession : TrackedEntity
{
    public Int32 TabletUserSessionId { get; set; }
    public Int32 ResponseSeriesId { get; set; }
    public Int32? TabletId { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime? ClosedDate { get; set; }

    public virtual Tablet Tablet { get; set; }
    public virtual ResponseSeries ResponseSeries { get; set; }
}

I configure the mapping like so:

public TabletUserSessionMap()
{
    HasRequired(tus => tus.ResponseSeries).WithOptional(rs => rs.TabletUserSession);
}

When I try to create a new ResponseSeries and a new TabletUserSession for it like so:

responseSeries.TabletUserSession = new TabletUserSession
{
    StartDate = DateTime.Now,
    TabletId = request.TabletId,
};

context.ResponseSeries.Add(responseSeries);
context.SaveChanges();

An error is thrown when inserting TabletUserSession because EF tries to insert the ResponseSeriesId into TabletUserSessionId.

INSERT [dbo].[TabletUserSession]
       ([TabletUserSessionId],
        [ResponseSeriesId],
        [TabletId],
        [StartDate],
        [ClosedDate],
        [Version],
        [CreatedUserId],
        [CreatedDate],
        [LastUpdateUserId],
        [LastUpdateDate])
VALUES (4404 /* @0 */, -- <--This is going into the wrong field!
        0 /* @1 */,
        9 /* @2 */,
        '2014-03-06T13:30:03' /* @3 */,
        NULL,
        1 /* @4 */,
        '801162722' /* @5 */,
        '2014-03-06T13:30:03' /* @6 */,
        '801162722' /* @7 */,
        '2014-03-06T13:30:03' /* @8 */)

I'm at wits end here. I've tried changing the mapping in various ways, but all I can do is get it to throw different exceptions. What am I not seeing?

Was it helpful?

Solution

For a one-to-one relationship to exist. The primary key is the same on both entities.

On the dependent table, the primary key is also the foreign key to the related entity.

In your example:

public class ResponseSeries : TrackedEntity
{
    public ResponseSeries()
    {
        Responses = new Collection<Response>();
    }
    public Int32 ResponseSeriesId { get; set; }

    public virtual TabletUserSession TabletUserSession { get; set; }
    public virtual ICollection<Response> Responses { get; set; }

}

public class TabletUserSession : TrackedEntity
{
    // this should not exist
    public Int32 TabletUserSessionId { get; set; }

    // this should be the primary key of this entity
    // it is also the foreign key to the ResponseSeriesId
    public Int32 ResponseSeriesId { get; set; }
    public Int32? TabletId { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime? ClosedDate { get; set; }

    public virtual Tablet Tablet { get; set; }
    public virtual ResponseSeries ResponseSeries { get; set; }
}

ResponseSeriesId is the primary key and is the prinicpal entity in the relationship. In this case, the primary key of your TabletUserSession entity needs to be ResponseSeriesId. It does not have an identity of its own, because otherwise it's not really one to zero or one.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top