我有以下C#Entity Framework代码定义的第一个实体:
class Program
{
static void Main(string[] args)
{
var context = new MyContext();
var person = new Person
{
FirstName = "Nadege",
LastName = "Deroussen",
BirthDate = DateTime.Now,
AccessCode = new AccessCode { Code = "ABC" }
};
context.Persons.Add(person);
var accessCode = new AccessCode { Code = "MGH" };
context.AccessCodes.Add(accessCode);
context.SaveChanges();
var person = context.Persons.Where(e => e.Id == 1).Single();
person.AccessCodeId = 2;
context.SaveChanges();
Console.Write("Person saved !");
Console.ReadLine();
}
}
public class Person
{
public int Id { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public DateTime BirthDate { get; set; }
public int AccessCodeId { get; set; }
[ForeignKey("AccessCodeId")]
public virtual AccessCode AccessCode { get; set; }
}
public class AccessCode
{
public int Id { get; set; }
public string Code { get; set; }
}
public class MyContext : DbContext
{
public DbSet<Person> Persons { get; set; }
public DbSet<AccessCode> AccessCodes { get; set; }
}
在Main
方法中,在分配AccessCodeId = 2
后,如果我检查了此人的AccessCode
引用,它仍然指向AccessCode
Id == 1
}。如何自动更新?
我正在学习EF,所以如果这没有意义,请原谅。
答案 0 :(得分:4)
更改外键属性值后,必须调用ChangeTracker的DetectChanges()方法
person.AccessCodeId = 2;
context.ChangeTracker.DetectChanges();
注意:我已经在@lucask代码和您的代码上测试了这种行为。您的代码只需要更正person
变量的第二个声明。
答案 1 :(得分:2)
最后,我使用以下代码获得了预期的行为:
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
Database.SetInitializer<TestContext>(new DropCreateDatabaseAlways<TestContext>());
var context = new TestContext();
var child = new Child { };
var parent = new Parent { Child = child };
context.Parents.Add(parent);
context.Children.Add(new Child { });
context.SaveChanges();
context.Parents.First().ChildId = 2;
context.SaveChanges();
}
}
public class Parent
{
public int Id { get; set; }
public virtual int ChildId { get; set; }
public virtual Child Child { get; set; }
}
public class Child
{
public int Id { get; set; }
}
public class TestContext : DbContext
{
public DbSet<Parent> Parents { get; set; }
public DbSet<Child> Children { get; set; }
}
}
图像显示了调试会话,因为在分配ChildId之后(在调用SaveChanges()之前),Child属性也会被正确更新。感谢所有提出宝贵意见的人。
答案 2 :(得分:1)
好吧,我不同意@David。 Code First,Database First或Model First只是实现相同目标的不同方法。 Code First和Data Annotations或Fluent API非常强大。你只需要学习如何使用它。
您的代码将有效。首先删除[ForeignKey("AccessCodeId")]
。它是多余的,无论如何你把它放在错误的属性上。 Code First会通过约定将AccessCodeId
设置为外键。 AccessCode
是导航属性,不会在数据库中生成,只是为了让您的生活更轻松。有关更多信息,请阅读以下文章:Code First Conventions。
这是工作代码(我测试过):
public class Person
{
public int Id { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public DateTime BirthDate { get; set; }
public int AccessCodeId { get; set; }
public virtual AccessCode AccessCode { get; set; }
}
public class AccessCode
{
public int Id { get; set; }
public string Code { get; set; }
}
public class MyContext : DbContext
{
public DbSet<Person> Persons { get; set; }
public DbSet<AccessCode> AccessCodes { get; set; }
}
class Program
{
static void Main(string[] args)
{
Database.SetInitializer<MyContext>(new DropCreateDatabaseAlways<MyContext>());
var context = new MyContext();
var person = new Person
{
FirstName = "Nadege",
LastName = "Deroussen",
BirthDate = DateTime.Now,
AccessCode = new AccessCode { Code = "ABC" }
};
context.Persons.Add(person);
var accessCode = new AccessCode { Code = "MGH" };
context.AccessCodes.Add(accessCode);
context.SaveChanges();
var person2 = context.Persons.FirstOrDefault();
person2.AccessCodeId = 2;
// or person2.AccessCode = accessCode;
context.SaveChanges();
Console.Write("Person saved !");
Console.ReadLine();
}
}
更改将在数据库上下文中显示。