简体   繁体   中英

Mapping for one to one with nullable value

I have two entity classes, Contact and User .

The User has ContactID as foreign key to Contact . I can show relation of the User to Contact .

Now i also need Contact to User relation with the same foreign key in User table (not in Contact )

public class Contact{
   public int ContactID {get;set;}
   // This relation doesn't work
   // Need to Make this Work
   public User ContactUser {get;set;}
}

public class User {
   public string Id {get;set;}
   public int? ContactID {get;set;}
   // This Relation works
   [ForeignKey("ContactID")]
   public Contact Contact {get;set;}
}

So i need to make the ContactUser relation work on Contact . What kind of mapping should i use?


Edit

As suggested I used : modelBuilder.Entity<Contact>().HasRequired(c => c.ContactUser).WithOptional(pi => pi.Contact); I removed ForeignKey attribute from User , it as causing Multiplicity...error

But i get error Like: Invalid column name 'User_Id'.

What you are looking for is a

One to Zero-or-One Mapping

There is a great anwser here on StackOverflow .


In your Case explicit is following required:

  • modelBuilder needs the WithOptional-Methode

    .WithOptional(pi => pi.Contact);

  • no Property for the ContactID

Example for EF 6.0

public class Contact
{
    [Key]
    public int ContactId { get; set; }

    public string ContactName { get; set; }
    public User ContactUser { get; set; }
}

public class User
{
    [Key]
    public int UserId { get; set; }

    public string UserName { get; set; }
    public Contact Contact { get; set; }
}

In the DbContext-Class:

public class CodeFirstContext : DbContext
{
    public CodeFirstContext()
    {
        Database.SetInitializer(new DropCreateDatabaseIfModelChanges<CodeFirstContext>());            
    }

    public DbSet<Contact> Contacts { get; set; }
    public DbSet<User> Users { get; set; }


    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
          .HasRequired(co => co.Contact)
          .WithOptional(cu => cu.ContactUser);

        base.OnModelCreating(modelBuilder);
    }
}

In this Case now says User's Contact property is optional and Contact's User property is required. I hope this is the right constellation for your project.

Console Test

class Program
{
    static void Main(string[] args)
    {
        using (var db = new CodeFirstContext())
        {
            Console.Write("Enter a name: ");
            var name = Console.ReadLine();

            var cont = new Contact { ContactName = name };
            db.Contacts.Add(cont);
            db.SaveChanges();

            var usr = new User { UserName = "MyUsername", Contact = cont };
            db.Users.Add(usr);
            db.SaveChanges();

            var query = from b in db.Contacts
                        orderby b.ContactName
                        select b;

            Console.WriteLine("All contacts in the database:");
            foreach (var item in query)
            {
                Console.WriteLine(item.ContactName);
            }

            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }
    }
}

Try this:

public class Contact
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int ContactId { get; set; }

    public string ContactName { get; set; }
    [ForeignKey("ContactId")]
    public User ContactUser { get; set; }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM