0

My models look the following:

public class Job
{
    public int Id { get; set; }
    public virtual JobResult Result { get; set; }
}
public class JobResult
{
    [Key, ForeignKey("Job")]
    public int JobId { get; set; }
    [Required]
    public virtual Job Job { get; set; }
}

As you see the relationship is a required one-to-one. When I try to create and save a job:

Job job = new Job();
job.Result = new Result();
context.Jobs.add(job);
context.SaveChanges();

I get the following error:

Unable to determine a valid ordering for dependent operations. Dependencies may exist due to foreign key constraints, model requirements, or store-generated values.

I don't quite understand the error message. What does it mean and what could be causing this error?

JensOlsen112
  • 1,279
  • 3
  • 20
  • 26
  • possible duplicate of [How do I create a real one-to-one relationship in SQL Server](http://stackoverflow.com/questions/10292355/how-do-i-create-a-real-one-to-one-relationship-in-sql-server). I'm pretty sure it is technically impossible in SQL Server to have a True 1 to 1 relationship, as that would mean you would have to insert both records at the same time (otherwise you'd get a contraint error on insert), in both tables, with both tables having a foreign key relationship to each other. – Erik Philips Jan 28 '15 at 19:06
  • @ErikPhilips - He mentions in a comment below that it's actually 1:0..1 not 1:1, as JobResult is optional – Erik Funkenbusch Jan 28 '15 at 19:10
  • @ErikFunkenbusch the questions should have been updated, as all questions should be self sufficient and not require anyone to read comments or comments of answers. – Erik Philips Jan 28 '15 at 19:12
  • 1
    @ErikPhilips - I agree, just pointing it out... – Erik Funkenbusch Jan 28 '15 at 19:13

2 Answers2

3

Your case is not valid beacose this is a circular reference. What must be done EF:

  1. INSERT INTO JobResults(....., Job_Id) VALUES (....., @JobId);

EF can not do this becase Job not inserted and does not have Id.

  1. INSERT INTO Jobs(....., JobResult_Id) VALUES (....., @JobResultId);

EF as well can not do this becase JobResult not inserted and does not have Id. This is a vicious cycle.

You may revise your model. Get rid of one of the links. Example:

public class Job
{
    public int Id { get; set; }
    public virtual JobResult Result { get; set; }
}

public class JobResult
{
    public int Id { get; set; }
    public virtual Job Job { get; set; }
}

class JobResultConfiguration : EntityTypeConfiguration<JobResult>
{
    public JobResultConfiguration()
    {
        HasRequired(e => e.Job).WithRequiredPrincipal(e => e.Result); // one-to-one
    }
}

public class MyContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new JobResultConfiguration());
    }
}

This will allow you to do:

Job job = new Job();
job.Result = new Result();
context.Jobs.add(job);
context.SaveChanges();

EF make one-to-one relationship: two entity with two entity with identical primary key.

More detail about Fluent Api: https://msdn.microsoft.com/en-us/data/jj591620.aspx

Or your place revised model domain. As you circular links, i would try to get rid of the one link (or from Job or from JobResult)

Patrick
  • 1,717
  • 7
  • 21
  • 28
sribin
  • 1,736
  • 1
  • 13
  • 21
  • I see. What would you suggest me to do to solve this issue? Also, why can EF not insert Job into the DB? JobResult is optional so can't it just insert 0 in JobResultId? – JensOlsen112 Jan 28 '15 at 18:55
  • I see. However I would prefer to keep my operation as a single transaction. Is there really no way to accomplish this? – JensOlsen112 Jan 28 '15 at 19:00
  • I updated my answer above. If you can give up one reference, the last option is what you need. – sribin Jan 28 '15 at 19:08
  • Removing one of the references seems like the best choice (although not what I had hoped for). If none of the fields were marked [Required] would I still not b able to insert them in a single transaction? I mean one-to-one relationships must be pretty common right? – JensOlsen112 Jan 28 '15 at 19:10
  • Yes, you will still not be able to perform this transaction. You could execute this transaction on pure SQL. When designing the domain model is a good practice - minimize the number of links in the entities. This will simplify the mapping as well as the logic domain. – sribin Jan 28 '15 at 19:13
  • If you not used in domain logic property JobResult in Job entity then you will be better to get rid of this link. – sribin Jan 28 '15 at 19:20
  • The issue I see with removing the reference from Job is the fact that JobResult won't get added to the context when I add the job which makes it really impractical to implement IMO. – JensOlsen112 Jan 28 '15 at 19:25
  • You can remote Job property in JobResult and save JobResult property in Job? – sribin Jan 28 '15 at 19:42
  • You can still choose a solution with call two SaveChanges method, but befor open transaction in context (context.Database.OpenTransaction()) and after last SaveChange call transaction.Commit(). – sribin Jan 28 '15 at 19:49
  • Thnaks for your solutions. I think I will go with opening a transaction but would you mind explaining what you exactly meant with "remote the Job property" ? – JensOlsen112 Jan 28 '15 at 21:08
  • I would in your place revised model domain. As you circular links, i would try to get rid of the one link (or from Job or from JobResult). – sribin Jan 29 '15 at 05:29
1

Your [Required] field is on the wrong element for the type of operation you are performing. Because you are Requiring a JobResult to have a Job, you can Create a JobResult and then create the Dependent Job (which has no requirements), but not the other way around. If you try to create it from the Job end, the Job isn't attached to the JobResult until it is created, but it can't be created until the JobResult is, creating a circular reference.

Claies
  • 22,124
  • 4
  • 53
  • 77
  • I tried removing the [Required] from the JobResult.Job - however now I get this error message: "Unable to determine a valid ordering for dependent operations. Dependencies may exist due to foreign key constraints, model requirements, or store-generated values." – JensOlsen112 Jan 28 '15 at 19:06
  • you may need to use the fluentApi to configure the order of operations. see http://stackoverflow.com/questions/26389707/ef-code-first-one-to-one-relationship-multiplicity-is-not-valid-in-role-in-re/26425364#26425364 – Claies Jan 28 '15 at 19:09
  • I've looked the thread through but I don't quite see how FluentAPI would apply as a solution in my case. Would you mind showing me an example? – JensOlsen112 Jan 28 '15 at 19:18