Add child entities to database and assign them to parent object in database Entity Framework Core

c# entity-framework-core xamarin.forms

Question

I have a datamodel named "Document" which looks like this:

public class Document
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    //[ForeignKey("Id")]
    public List<DocumentLine> Lines { get; set; }

    public DateTime PurchaseDate { get; set; }

    public double TotalValue { get; set; }
}

It contains a list of the child object "DocumentLines" which looks like this:

public class DocumentLine
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public int LineId { get; set; }

    public int DocumentId { get; set; }

    //public virtual Document ParentDocument { get; set; }

    public string ItemName { get; set; }

    public double ItemPrice { get; set; }

    public double ItemId { get; set; }

    public int Quantity { get; set; }
}

I created a repository for each DataModel in my solution, so I have a documentRepository and a documentLinesRepository.

Currently I am facing several errors while creating a new document which contains a list of its child documentLines.

If i want to create a new document in the database the following code is executed first:

    public async Task<Document> CreateNewAsync()
    {
        Document document = new Document()
        {
            Lines = null,
            PurchaseDate = DateTime.Now,
        };

        var newDocument = await databaseContext.Documents.AddAsync(document);
        await databaseContext.SaveChangesAsync();
        return newDocument.Entity;
    }

And this code works as it should, but now if I want to create a new object of type DocumentLine and add it to the database with the following code:

    public async Task<DocumentLine> CreateNewAsync()
    {
        try
        {
            DocumentLine documentLine = new DocumentLine();

            var newDocumentLine = await databaseContext.DocumentLines.AddAsync(documentLine);
            await databaseContext.SaveChangesAsync();
            return newDocumentLine.Entity;
        }
        catch(Exception ex)
        {
            return null;
        }
    }

I get the following error in the line where the "documentLine" should be added to the database:

"SQLite Error 19: 'FOREIGN KEY constraint failed'."

First of all I don't see where a foreign key is set for the instance of type "DocumentLine".

I tried several other things, as well as assigning a instance of the parent of type "Document" in each DocumentLine, but this got me an error as well.

How it should work

My question is how I could properly implement the behavior that a document is saved in the database and each line got saved seperatly (from the documentLinesRepository) and only at the end when all lines are set, the document will be updated in the database containing a full list of DocumentLines objects.

Sorry in advance if this is a beginner question, but I tried to solve this error for a few days until now and I didn't found the right solution with google atm.

1
1
9/8/2018 5:06:53 PM

Accepted Answer

"First of all I don't see where a foreign key is set for the instance of type "DocumentLine"."

Well, then first of all - check that. In the actual database created by EF. You're most probably gonna find an FK on DocumentId in your DocumentLines table.

Your Document and DocumentLines are in a 1toMany relationship - a DocumentLine makes no sense without a Document as a parent. So you can't insert an orphaned DocumentLine to the database. Uncomment the

public virtual Document ParentDocument { get; set; }

and assign the parent before inserting:

public async Task<DocumentLine> CreateNewAsync(Document parent)
{
    try
    {
        DocumentLine documentLine = new DocumentLine();

        documentLine.ParentDocument = parent;

        var newDocumentLine = await databaseContext.DocumentLines.AddAsync(documentLine);
        await databaseContext.SaveChangesAsync();
        return newDocumentLine.Entity;
    }
    catch(Exception ex)
    {
        return null;
    }
}

This tells EntityFramework "Hey, these two are related." EF then will figure out correct relationship values in the database by itself.

Tell me if it fixes the issue, as all is dependent on the initial guess of FK on DocumentId.

2
9/8/2018 5:27:13 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow