2016-06-21 10 views
0

1つのレコードを更新し、そのレコードに関連するエンティティを初めて追加する方法を理解し、新しく作成した外部キ​​ーで元のレコードを更新する記録。関連するエンティティを追加した後にエンティティの外部キーを更新する

たとえば、2つのテーブルがあるとします。1つは人(tbl_person)、もう1つはアドレス(tbl_address)です。

+----+------------+-----------+-----------+ 
| PK | First Name | Last Name | AddressFK | 
+----+------------+-----------+-----------+ 
| 1 | Michael | Jordan |   1 | 
| 2 | Lebron  | James  |   | 
+----+------------+-----------+-----------+ 

    public int PersonID { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public int? AddressID { get; set; } 
    public virtual tbl_Address tbl_Address { get; set; } 

    entityBuilder 
     .HasOne(t => t.tbl_Address) 
     .WithOne(t => t.tbl_Person) 
     .HasForeignKey<tbl_Person>(d => d.AddressID) 
     .IsRequired(false); 

+----+-------------------+----------+-------+ 
| PK | Address Line 1 | City | State | 
+----+-------------------+----------+-------+ 
| 1 | 123 Sesame Street | New York | NY | 
+----+-------------------+----------+-------+ 

    public int AddressID { get; set; } 
    public string AddressLine1 { get; set; } 
    public string City { get; set; } 
    public string State { get; set; } 
    public virtual tbl_Person tbl_Person { get; set; } 

私のアプリは、更新が必要なJSONレコードを受け取ります。

{ 
    "address": { 
    "addressLine1": "789 Hollywood Ave", 
    "city": "Hollywood", 
    "state": "CA" 
    }, 
    "firstname": "Lebron", 
    "lastname": "Brown", 
    "id": 2, 
} 

私はLebron BrownをLebron Brownに更新し、彼のアドレスを追加する必要があります。今、私は、レコードを検索し、次の操作を行い、それが個人の記録を更新し、アドレス・レコードを作成します。

var person = _db.tbl_Person 
    .Include(t => t.tbl_address) 
    .Where(t => t.Id == json.id).First(); 

person.firstname = json.firstname; 
person.lastname = json.lastname; 
if(person.tbl_Address == null) 
{ 
    person.tbl_Address = new tbl_Address() { 
     AddressLine1 = json.address.addressLine1, 
     City = json.address.city, 
     State = json.address.state, 
    }; 
} 

db.SaveChanges(); 

私は人のAddressId保存、変更前に、新しく作成されたのAddressIdを等しくするためにしようとすると問題がありますそれは私に外来キー制約に関するエラーを与えます。

person.AddressID = person.tbl_Address.Id; 
db.SaveChanges(); 

助けてください。それはそれのように自動的に子エンティティの外部キーを生成していないので、私はそれはバグかもしれないと思うし始めているので、私はEntityFrameworkコアのGithubにクロスポストしまったあなたに

をクロスポストTO

LINKありがとうございましただと思う。 GitHubの問題には、サンプルプロジェクトが添付されています(ここに示す例よりやや複雑です)。確認したい場合は、エラーを複製してください:https://github.com/aspnet/EntityFramework/issues/5833

+0

データアノテーションまたはEntityTypeConfigurationsのいずれかを使用したクラス宣言が役立ちますが、基本的にFKを手動で更新しないのは、SaveChangesコールの前にすべてデフォルト値( 'default(int)== 0 ')それは例外があるからです。 –

+0

これは私の問題のサンプルです。実際のテーブルにはかなり近いです。私はクラス宣言を要求通りに追加しました。 – chris

+0

あなたの例では、 'person.tbl_Address'を設定することによって、EFはアドレスを挿入し、' Person'をすべて更新します。 –

答えて

0

モデルを正しく設定していれば、 AddressIDを設定する必要はありません。自動的に更新されます。 SaveChanges()が呼び出される前のAddressIDの値はdefault(int) == 0です。そのため例外が発生します。この宣言で十分です:

public class Person { 
    public int AddressID {get;set;} 
    [ForeignKey(nameof(Person.AddressID))] 
    public Address tbl_Address {get;set;} 
} 

TUが、私は人がすでにアドレスを持っている場合、それが更新されます、

if (json.address != null) 
{ 
    if(person.tbl_Address == null) 
    { 
     person.tbl_Address = new tbl_Address(); 
    } 
    person.tbl_Address.AddressLine1 = json.address.addressLine1, 
    person.tbl_Address.City = json.address.city, 
    person.tbl_Address.State = json.address.state 
} 

にこの方法を、コードを変更しますアドレスを更新し、そうでない場合は、新規作成します。外部キーの設定は必要ありません.EFがそれを処理します。エンティティは、すでにあなたのDBに存在する場合、このバリアントを使用してください:EFで

+0

私は最初、私がそれを実行し、予想どおりのアドレスを作成してもpersonIDテーブルにaddressIDを追加しなかったときまで、私はaddressIDを定義しなくてはならないと思っていました。私のテーブルはわずかに異なります。私は問題に集中するためにビジネスロジックを愚かにしましたが、全体的には同じです。これらのサンプルテーブルをテストして、同じ結果が得られるかどうかを確認するための素早いダムプロジェクトを行っています。 – chris

+0

必要に応じてサンプルを更新/挿入するように更新しました。 –

+0

EntityFramework Core Githubへのクロスポストが終わったのは、私がバグかもしれないと思っているからです。子エンティティに外来キーが自動的に生成されないためです。 GitHubの問題では、チェックアウトしたい場合にエラーが発生した場合に攻撃されたサンプルプロジェクトがあります:https://github.com/aspnet/EntityFramework/issues/5833 – chris

0

は関係を設定するには2つの方法、

  • FKプロパティの設定があります。

  • ナビゲーションプロパティの設定:このエンティティは、新しいエンティティの場合に使用します。 SaveChangesを呼び出すと、新しいエンティティがDBに保持され、FK列も設定されます。

そのAddressがすでに存在しているのであれば、あなたがする必要があるだけでは、そのIdを検索し、PersonエンティティでFKプロパティを設定しています。

Addressは、新しいインスタンスを作成し、その後、存在するとSaveChangesを呼び出さない場合は、次の

person.tbl_Address = new tbl_Address() { 
    AddressLine1 = json.address.addressLine1, 
    City = json.address.city, 
    State = json.address.state, 
}; 
db.SaveChanges(); 

それが呼び出した後、あなたがAddressIdがあなたのPersonエンティティに値を持っていることを見ることができるはずです。

+0

私の場合、人が存在し、アドレスは存在しません。私は人の姓を更新し、アドレスに移動して最初にアドレスを追加するだけでなく、そのアドレスIDを人に返してそのテーブルを更新する必要があります – chris

+0

こんにちは@chris、私の答えの最後の部分を見ましたか? – octavioccl

+0

EntityFramework Core Githubへのクロスポストが終わったのは、私がバグかもしれないと思っているからです。なぜなら、それは自動的に子エンティティに外部キーを生成していないからです。 GitHubの問題では、チェックアウトしたいエラーが発生したサンプルプロジェクトが攻撃されています:https://github.com/aspnet/EntityFramework/issues/5833 – chris

関連する問題