2

我定义了以下 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人员中的引用,它仍然指向AccessCodewith Id == 1。我怎样才能得到这个自动更新?

我正在学习EF,所以如果这没有意义,请原谅。

4

3 回答 3

4

更改外键属性值后,您必须调用 ChangeTracker 的 DetectChanges() 方法

person.AccessCodeId = 2;
context.ChangeTracker.DetectChanges();

注意:我已经在@lucask 代码和您的代码上测试了这种行为。您的代码只需要更正person变量的第二个声明。

于 2012-05-24T15:39:04.383 回答
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 属性也得到正确更新。感谢所有提出宝贵建议的人。

在此处输入图像描述

于 2012-05-26T09:27:36.550 回答
1

好吧,我不同意@David。Code First、Database First 或 Model First 只是实现相同目标的不同方法。并且带有数据注释或 Fluent API 的 Code First 非常强大。你只需要学习如何使用它。

您的代码将起作用。首先删除[ForeignKey("AccessCodeId")]. 这是多余的,无论如何你把它放在了错误的属性上。Code First 将按照惯例AccessCodeId设置为外键。是导航属性,不会在数据库中生成,它只是为了让您的生活更轻松。有关更多信息,请阅读本文:代码优先约定AccessCode

这是工作代码(我测试过):

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();
    }
}

更改将在数据库上下文中可见。

于 2012-05-24T13:43:53.620 回答