daveywc
daveywc

Reputation: 3146

Entity Framework Code First One to One Constraint Violation

Given the following simplified model:

public class Account
{
    public Account()
    {
        Id = Guid.NewGuid();
        ContactCard = new ContactCard();
    }

    //[ForeignKey("ContactCard")]
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Number { get; set; }
    public ContactCard ContactCard { get; set; }
}

public class ContactCard
{
    public ContactCard()
    {
        Id = Guid.NewGuid();
    }

    public Guid Id { get; set; }
    public Account Account { get; set; }
}

public class MightDbContext: DbContext
{
    public DbSet<Account> Accounts { get; set; }
    public DbSet<ContactCard> ContactCards { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Account>().HasRequired(x => x.ContactCard).WithOptional(x => x.Account);
    }
}

public class MightDbInitializer : DropCreateDatabaseIfModelChanges<MightDbContext>
{
    protected override void Seed(MightDbContext context)
    {
        var accounts = new List<Account> 
        {
            new Account()
            {
                Name = "Acme Corporation Pty. Ltd.",
                Number = "001ABC"
            },

            new Account()
            {
                Name = "Three Little Pigs Pty. Ltd.",
                Number = "002DEF"
            }
        };

        accounts.ForEach(c => context.Accounts.Add(c));
    }
}

And the following simple console program to iterate the contents of the Accounts and ContactCards collections:

static void Main(string[] args)
    {
        Database.SetInitializer<MightDbContext>(new MightDbInitializer());

        using (var context = new MightDbContext())
        {
            foreach (Account c in context.Accounts)
            {
                Console.WriteLine(c.ContactCard.Id);
            }

            var contactCards = context.ContactCards.ToList();  /* ERROR OCCURS HERE */

            foreach (ContactCard a in contactCards)
            {
                Console.WriteLine(a.Id);
            }
        }

        Console.Read();
    }

Why do I get the following error as soon as I try to access the ContactCards collection:

Multiplicity constraint violated. The role 'Account_ContactCard_Source' of the relationship 'InvestAdmin.Might.DataAccess.Account_ContactCard' has multiplicity 1 or 0..1.

When I look at the data that has actually been stored in the database tables all seems to be correct. In fact here is that data:

Accounts:
Id  Name    Number
ab711bad-1b32-42ca-b68b-12f7be831bd8    Acme Corporation Pty. Ltd.  001ABC
dc20a1dd-0ed4-461d-bc9c-04a85b555740    Three Little Pigs Pty. Ltd. 002DEF

ContactCards:
Id
dc20a1dd-0ed4-461d-bc9c-04a85b555740
ab711bad-1b32-42ca-b68b-12f7be831bd8

And for completeness here is the Account_ContactCard foreign key constraint as defined in the database:

-- Script Date: 06/12/2011 7:00 AM  - Generated by ExportSqlCe version 3.5.1.7
   ALTER TABLE [Accounts] ADD CONSTRAINT [Account_ContactCard] FOREIGN KEY ([Id]) REFERENCES [ContactCards]([Id]) ON DELETE NO ACTION ON UPDATE NO ACTION;

I have been reading all I can on defining one to one relationships in Code First and have tried many different configurations. All end up back at the same problem.

Upvotes: 3

Views: 579

Answers (1)

daveywc
daveywc

Reputation: 3146

I found that I could resolve this problem by moving the creation of the associated ContactCard from the Account constructor into the actual creation of the Account objects in the Seed method of the DBInitializer. So it appears that it was not (directly) a problem with the One to One relationship.

Upvotes: 2

Related Questions