简体   繁体   English

EntityFramework Code首先添加1到1个数据

[英]EntityFramework Code First 1 to 1 data add

I'm creating a database using the code-first way. 我正在使用代码优先的方式创建数据库。 I have two entities in a 1 to 1 relation, but I don't really know how to instantiate them. 我有两个1对1关系的实体,但我真的不知道如何实例化它们。

Assume those are my entities: 假设这些是我的实体:

public class Foo
{
    [Key]
    public int Id {get;set;}
    [ForeignKey("BigFoo")]
    public int BigFooId {get;set;}
    public virtual BigFoo BigFoo {get;set;}
}

public class BigFoo
{
    [Key]
    public int Id {get;set;}
    [ForeignKey("Foo")]
    public int FooId{get;set;}
    public virtual Foo Foo {get;set;}
}

This is my code: 这是我的代码:

Foo foo = new Foo();
foo = db.Foo.Add(foo);

BigFoo big = new BigFoo {Foo = foo, FooId = foo.Id};
big = db.BigFoo.Add(big);

//HERE is my doubt
//I don't know if I have to add the relation also in the Foo object
//Do i need the following code?

//foo.BigFoo = big;
//foo.BigFooId = big.Id;
//db.Foo.Attach(foo);
//var entry = db.Entry(foo);
//entry.Property(x => x.BigFoo).IsModified = true;

db.SaveChanges();

The relation is already set in my BigFoo object declaration, do I need anyway to set this relation also in the Foo object or it will be automatically assigned? 该关系已在我的BigFoo对象声明中设置,我是否还需要在Foo对象中设置此关系,否则它将自动分配?

Thanks all for the help. 谢谢大家的帮助。

EDIT: 编辑:

I have another doubt: I have my foreign keys named relatedentityIdField. 我有另一个疑问:我的外键名为relateddentityIdField。

I have to istantiate also them with the 我必须和他们一起解决这个问题

foo.BigFooId = big.Id;

Or those relations are automatically filled? 或者那些关系是自动填充的?

ADD EXAMPLE-EDIT 添加示例 - 编辑

An example can be the relation Nation - President 一个例子可以是国家 - 总统的关系

Every Nation has only one president, and every president is only the president of a Nation. 每个国家只有一位总统,每位总统都只是一个国家的总统。

How can I set this relation using Code-First? 如何使用Code-First设置此关系?

With current model what you really have is two one to many unidirectional relationships. 使用当前模型,您真正拥有的是两个一对多的单向关系。 To create a one to one relationship using Code First you must define the PK of the dependent entity as FK of the relationship too (check this link for a detailed explanation). 要使用Code First创建一对一关系,您必须将依赖实体的PK定义为关系的FK(请查看此链接以获取详细说明)。

public class Foo
{
  public int Id{get;set;}

  public virtual Boo Boo {get;set;}
}

public class Boo
{
  [Key, ForeignKey("Foo")]
  public int FooId{get;set;}

  public virtual Foo Foo {get;set;}
}

With this model, you could add data as follows: 使用此模型,您可以按如下方式添加数据:

  1. If you want to create a new Foo and Boo and you want to relate them, you can do the following: 如果要创建新的FooBoo并且想要关联它们,可以执行以下操作:

     var boo=new Boo(); var foo=new Foo{Boo=boo }; context.Foos.Add(foo); context.SaveChanges(); 

You should see Foo navigation property in your Boo entity is also filled. 您应该看到Boo实体中的Foo导航属性也已填充。

  1. If Foo already exist and you want to create a new Boo related with that foo: 如果Foo已经存在并且你想创建一个与该foo相关的新Boo

    You can set the Boo navigation property in your foo entity: 您可以在foo实体中设置Boo导航属性:

     var foo= context.Find(yourId); foo.Boo=new Boo(); context.SaveChanges(); 

    Or you can just set the PK/FK property of your new Boo entity: 或者您可以设置新Boo实体的PK / FK属性:

      var fooId=1;// You already have the Foo id var boo = new Boo() { FooId = fooId}; context.Boos.Add(boo); context.SaveChanges(); 

Whit your model, as I said before, you have two different relationships, so your navigation properties aren't really related. 如前所述,使你的模型发白,你有两种不同的关系,所以你的导航属性并不真正相关。 If you want to prove that, add two collections to your entities: 如果您想证明这一点,请向您的实体添加两个集合:

public class Foo
{
    [Key]
    public int Id {get;set;}
    [ForeignKey("BigFoo")]
    public int? BigFooId {get;set;}
    public virtual BigFoo BigFoo {get;set;}
    public virtual ICollection<BigFoo> BigFoo{get;set;}// Add this property
}

public class BigFoo
{
    [Key]
    public int Id {get;set;}
    [ForeignKey("Foo")]
    public int? FooId { get; set; }
    public virtual Foo Foo {get;set;}
    public virtual ICollection<Foo> Foos{get;set;}// Add this property
}

And later try this: 然后尝试这个:

using (var context=new MyContext())
{
    var foo = new Foo();
    context.Foos.Add(foo);
    context.SaveChanges();

    var boo = new BigFoo() { FooId = foo.Id};

    context.Boos.Add(boo);
    context.SaveChanges();
 }

After the last SaveChanges you will Foo nav. 在最后的SaveChanges之后,你将Foo导航。 property in boo instance and BigFoos nav property in foo instance are properly filled. boo实例中的属性和foo实例中的BigFoos nav属性已正确填充。

Notes: I changed your navigation properties to virtual to meet one of the requirements of Lazy Loading , and I also changed your FK properties as nullables to avoid cycles of cascading delete. 注意:我将导航属性更改为virtual以满足延迟加载的要求之一,并且还将您的FK属性更改为nullables以避免级联删除循环。 Code First did not setup a cascade delete for the optional relationships. Code First没有为可选关系设置级联删除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM