Fallingsappy
Fallingsappy

Reputation: 303

How to Update Entity with multiple one-to-one relationship

I have Entities: DbDropPhoto, DbReferencePhoto and DbSimpleLine. DbSimpleLines is used by bReferencePhoto and DbDropPhoto. I want to make DbSimpleLine linkable to only one of it using entities per DbSimpleLine. For example if DbSimpleLine is DropPhotoHorizontalLine, the other two properties will be null. I've searched for some solution and found this one: http://csharpwavenet.blogspot.com/2013/06/multiple-foreign-keys-with-same-table.html But now i'm realy confused. For example, according to example my DbSimpleLine class should have collection of ReferencePhoto, but in reality one DbSimpleLine can have only one ReferencePhoto. I did something wrong while configuring the relationship? For relationship configuration i use fluent API:

        modelBuilder.Entity<DbDropPhoto>()
            .HasOptional(b => b.SimpleHorizontalLine)
            .WithMany(a => a.DropPhotoHorizontalLine)
            .HasForeignKey(b => b.SimpleHorizontalLineId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<DbDropPhoto>()
            .HasOptional(b => b.SimpleVerticalLine)
            .WithMany(a => a.DropPhotoVerticalLine)
            .HasForeignKey(b => b.SimpleVerticalLineId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<DbReferencePhoto>()
            .HasOptional(b => b.SimpleReferencePhotoLine)
            .WithMany(a => a.ReferencePhoto)
            .HasForeignKey(b => b.SimpleReferencePhotoLineId)
            .WillCascadeOnDelete(false);

.WithMany() confuses me, because SimpleVerticalLine (for example) shouldn't have many of DropPhoto.

[Table("SimpleLines")]
public class DbSimpleLine
{
    [Key]
    public Guid SimpleLineId { get; set; }

    public ICollection<DbReferencePhoto> ReferencePhoto { get; set; }
    public ICollection<DbDropPhoto> DropPhotoHorizontalLine { get; set; }
    public ICollection<DbDropPhoto> DropPhotoVerticalLine { get; set; }
}

public class DbReferencePhoto
{
    [Key]
    public Guid ReferencePhotoId { get; set; }

    public Guid? SimpleReferencePhotoLineId { get; set; }
    public DbSimpleLine SimpleReferencePhotoLine { get; set; }
}

[Table("DropPhotos")]
public class DbDropPhoto
{
    [Key]
    public Guid DropPhotoId { get; set; }

    public Guid? SimpleHorizontalLineId { get; set; }
    public DbSimpleLine SimpleHorizontalLine { get; set; }

    public Guid? SimpleVerticalLineId { get; set; }
    public DbSimpleLine SimpleVerticalLine { get; set; }
}

Also when i'm trying to save dbDropPhoto to Database i'm getting an exception:

System.InvalidOperationException: 'Multiplicity constraint violated. The role 'DbDropPhoto_Drop_Target' of the relationship 'DDrop.Db.DbDropPhoto_Drop' has multiplicity 1 or 0..1.'

code for save method:

public async Task UpdatDropPhoto(DbDropPhoto dropPhoto)
{
    using (var context = new DDropContext())
    {
        var dropPhotoToUpdate = await context.DropPhotos.FirstOrDefaultAsync(x => x.DropPhotoId == dropPhoto.DropPhotoId);

        try
        {                  
            if (dropPhoto.SimpleVerticalLine != null)
                context.SimpleLines.Add(dropPhoto.SimpleVerticalLine);
            if (dropPhoto.SimpleHorizontalLine != null)
                context.SimpleLines.Add(dropPhoto.SimpleHorizontalLine);
            context.Entry(dropPhotoToUpdate).CurrentValues.SetValues(dropPhoto);

            await context.SaveChangesAsync();
        }
        catch (Exception e)
        {
            throw new Exception(e.Message);
        }
        await context.SaveChangesAsync();
    }
}

Upvotes: 0

Views: 64

Answers (1)

Fallingsappy
Fallingsappy

Reputation: 303

Ended up doing it like this:

       modelBuilder.Entity<DbDropPhoto>()
            .HasOptional(c => c.SimpleHorizontalLine)
            .WithMany()
            .HasForeignKey(s => s.SimpleHorizontalLineId);

        modelBuilder.Entity<DbDropPhoto>()
            .HasOptional(c => c.SimpleVerticalLine)
            .WithMany()
            .HasForeignKey(s => s.SimpleVerticalLineId);

        modelBuilder.Entity<DbReferencePhoto>()
            .HasOptional(c => c.SimpleReferencePhotoLine)
            .WithMany()
            .HasForeignKey(s => s.SimpleReferencePhotoLineId);

[Table("SimpleLines")]
public class DbSimpleLine
{
    [Key]
    public Guid SimpleLineId { get; set; }
}

[Table("ReferencePhotos")]
public class DbReferencePhoto
{
    [Key]
    public Guid ReferencePhotoId { get; set; }     
    public Guid? SimpleReferencePhotoLineId { get; set; }
    [ForeignKey("SimpleReferencePhotoLineId")]
    public virtual DbSimpleLine SimpleReferencePhotoLine { get; set; }
}

[Table("DropPhotos")]
public class DbDropPhoto
{
    [Key]
    public Guid DropPhotoId { get; set; }
    public Guid? SimpleHorizontalLineId { get; set; }
    [ForeignKey("SimpleHorizontalLineId")]
    public virtual DbSimpleLine SimpleHorizontalLine { get; set; }
    public Guid? SimpleVerticalLineId { get; set; }
    [ForeignKey("SimpleVerticalLineId")]
    public virtual DbSimpleLine SimpleVerticalLine { get; set; }
}

Upvotes: 1

Related Questions