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を確認すると、まだwith をAccessCode指しています。この自動更新を取得するにはどうすればよいですか?AccessCodeId == 1

私はEFを学んでいるので、これが意味をなさない場合はご容赦ください。

4

3 に答える 3

4

外部キー プロパティの値を変更した後、ChangeTracker の DetectChanges() メソッドを呼び出す必要があります。

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

注: @lucask コードとあなたのコードでもこの動作をテストしました。あなたのコードは、person変数の 2 番目の宣言を修正するだけで済みました。

于 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に同意しません。コード ファースト、データベース ファースト、またはモデル ファーストは、同じ目標を達成するための方法が異なるだけです。また、Data Annotations または Fluent API を使用した Code First は非常に強力です。使い方を学ぶしかありません。

あなたのコードは動作します。まず、削除し[ForeignKey("AccessCodeId")]ます。それは冗長であり、とにかく間違ったプロパティに配置しました。Code First は慣例AccessCodeIdにより外部キーとして設定されます。はナビゲーション プロパティであり、データベースには生成されません。これは、あなたの生活を楽にするためだけのものです。詳細については、次の記事を参照してください: Code First ConventionsAccessCode

ここに作業コードがあります(私がテストしました):

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 に答える