gpt4 book ai didi

c# - IDbSetExtensions.AddOrUpdate 和关系

转载 作者:太空狗 更新时间:2023-10-29 22:33:42 25 4
gpt4 key购买 nike

IDbSetExtensions.AddOrUpdate 旨在帮助编写无论数据库是空的还是已填充的代码都可以正常工作。但是链接对象需要不同的代码。当数据库为空时,对象还没有 ID,您可以通过分配导航属性来链接它们。但是,当对象已经存在时,导航属性不起作用,您需要直接设置外键。 导航属性在这两种情况下都适用于代理,但代价是放弃 POCO。编辑:实际上,当两个实体都旧时,代理不起作用。

当 EF 尝试将 CountryID 设置为 0 时,此示例在第二次 SaveChanges 调用中崩溃:

public class Country
{
public virtual int ID { get; set; }
public virtual string Name { get; set; }
}

public class Person
{
public virtual int ID { get; set; }
public virtual string Name { get; set; }

public virtual int CountryID { get; set; }
public virtual Country Country { get; set; }
}

public class Context : DbContext
{
public DbSet<Person> Person { get; set; }
public DbSet<Country> Country { get; set; }
}

class Program
{
static void Foo()
{
using (var db = new Context())
{
//var c = new Country();
var c = db.Country.Create();
c.Name = "usa";
db.Country.AddOrUpdate(x => x.Name, c);

//var p = new Person();
var p = db.Person.Create();
p.Name = "billg";
p.Country = c;
db.Person.AddOrUpdate(x => x.Name, p);

db.SaveChanges();
}
}
static void Main()
{
Database.SetInitializer<Context>(new DropCreateDatabaseAlways<Context>());
Foo();
Foo();
}
}

如何使用 AddOrUpdate?

最佳答案

IDbSetExtensions.AddOrUpdate is meant to help write code that works the same whether the database is empty or populated.

AddOrUpdate 仅用于代码优先迁移的 Seed 方法。它不应该在普通代码中使用,因为它有很大的开销和一些限制。开销是对数据库和反射的额外查询。限制是它只检查你传递的主要实体而不是它的关系。每个关系都应该通过单独调用 AddOrUpdate 来处理:

static void Foo()
{
using (var db = new Context())
{
var c = new Country() {Name = "abc"};
db.Country.AddOrUpdate(x => x.Name, c);

var p = new Person()
{
Name = "me",
CountryID = c.ID,
Country = c
};

db.Person.AddOrUpdate(x => x.Name, p);
db.SaveChanges();
}
}

关于c# - IDbSetExtensions.AddOrUpdate 和关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9776902/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com