Ваша оригинальная модель в вопросе должна работать. Вы можете проверить это довольно легко:
- Создание нового консольного приложения (VS 2010)
- Назовите его "EFTestApp"
- Добавить ссылку на "EntityFramework.dll"
- Удалите содержимое Program.cs и скопируйте следующий код в файл
Program.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
namespace EFTestApp
{
public class User
{
public int Id { get; set; }
public int? DefaultAddressId { get; set; }
[ForeignKey("DefaultAddressId")]
public virtual Address DefaultAddress { get; set; }
public virtual ICollection<Address> Addresses { get; set; }
}
public class Address
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Context : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Address> Addresses { get; set; }
}
class Program
{
static void Main(string[] args)
{
using (var context = new Context())
{
try
{
User user = new User() { Addresses = new List<Address>() };
Address address1 = new Address() { Name = "Address1" };
Address address2 = new Address() { Name = "Address2" };
user.Addresses.Add(address1);
user.Addresses.Add(address2);
context.Users.Add(user);
context.SaveChanges();
// user has now 2 addresses in the DB and no DefaultAddress
user.DefaultAddress = address1;
context.SaveChanges();
// user has now address1 as DefaultAddress
user.DefaultAddress = address2;
context.SaveChanges();
// user has now address2 as DefaultAddress
user.DefaultAddress = null;
context.SaveChanges();
// user has now no DefaultAddress again
}
catch (Exception e)
{
throw;
}
}
}
}
}
В SQL Server Express создается новая БД с именем «EFTestApp.Context». Вы можете установить контрольные точки для каждого SaveChanges выше, перешагнуть и наблюдать за изменениями в БД.
Если посмотреть на отношения в базе данных, то их два, а в таблице Addresses
в БД есть столбец внешнего ключа User_Id
.
Я думаю, вы также можете удалить public int? DefaultAddressId { get; set; }
и [ForeignKey("DefaultAddressId")]
. Он создает те же таблицы базы данных и отношения с необязательным параметром DefaultAddress.
Возможно, вы хотите, чтобы отношение Address -> User
соответствовало требованиям (Адреса не могут жить одни в БД без Пользователя). Затем вы можете добавить это в класс Context:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>()
.HasMany(u => u.Addresses)
.WithRequired();
}
Это делает User_Id
в таблице адресов недействительными и устанавливает каскадное удаление по умолчанию. Таким образом, когда пользователь удаляется, все его адреса также удаляются.