gpt4 book ai didi

c# - 属性类型更改时不更新鉴别器

转载 作者:行者123 更新时间:2023-11-30 18:46:38 25 4
gpt4 key购买 nike

我有一个实体,它有一个抽象类型的属性。这将创建一个一对一的关系,该关系使用每个层次结构的表继承。一切似乎都在正常工作。

我可以创建一个 Item 并将 Base 属性设置为 ConcreteOne;一切都正确保存。但是,当我尝试将 Base 更新为 ConcreteTwo 时,EF 会使用新用户值更新数据库中的 Base 记录,但它不会更新类型的鉴别器。因此,ConcreteTwo 的额外数据得到保留,但鉴别器仍然显示 ConcreteOne

下面是一个暴露问题的简单例子

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
App_Start.EntityFrameworkProfilerBootstrapper.PreStart();

Database.SetInitializer(new DropCreateDatabaseAlways<DataContext>());

// Create our item with ConcreteOne for Base
using (var context = new DataContext())
{
var item = new Item
{
Base = new ConcreteOne { Name = "Item", Data = 3 }
};
context.Items.Add(item);
context.SaveChanges();
}

// Update Base with a new ConcreteTwo
using (var context = new DataContext())
{
var item = context.Items.FirstOrDefault();

var newBase = new ConcreteTwo()
{
Item = item,
Name = "Item 3",
User = new User { Name = "Foo" }
};

// If I don't set this to null, EF tries to create a new record in the DB which causes a PK exception
item.Base.Item = null;
item.Base = newBase;

// EF doesn't save the discriminator, but DOES save the User reference
context.SaveChanges();
}

// Retrieve the item -- EF thinks Base is still ConcreteOne
using (var context = new DataContext())
{
var item = context.Items.FirstOrDefault();
Console.WriteLine("{0}: {1}", item.Name, item.Base.Name);
}

Console.WriteLine("Done.");
Console.ReadLine();
}
}

public class DataContext : DbContext
{
public DbSet<Item> Items { get; set; }
}

public class User
{
public int Id { get; set; }
public string Name { get; set; }
}

public class Item
{
public int Id { get; set; }
public string Name { get; set; }
public virtual Base Base { get; set; }
}

public abstract class Base
{
public int Id { get; set; }
public string Name { get; set; }

[Required]
public virtual Item Item { get; set; }
}

public class ConcreteOne : Base
{
public int Data { get; set; }
}

public class ConcreteTwo : Base
{
public virtual User User { get; set; }
}
}

保存更改后,EF 生成以下 SQL:

update [dbo].[Bases]
set [Name] = 'Item 3' /* @0 */,
[User_Id] = 1 /* @1 */
where (([Id] = 1 /* @2 */)
and [User_Id] is null)

所以它几乎是正确的,但我希望在更新语句中看到 [Discriminator] = 'ConcreteTwo'。我的期望是没有根据的还是我做错了什么?

作为测试,我尝试使用 table-per-type 并且条目从 ConcreteOne 表中删除并添加到 ConcreteTwo 表中,正如我所期望的那样。所以它有效,但我的实际应用程序至少有七个子类型,并且检索 Base 属性的 SQL 语句变得非常讨厌。因此,如果可能的话,我当然希望使用 TPH 来完成此任务。

更新:我已验证该问题存在于 EF5 和 EF6 中。

最佳答案

这个问题是基于对发生更新的预期,这似乎是一个有争议的预期。目前,如果 TPH 层次结构未按预期运行,并且考虑到 EF6 目前处于测试阶段,您最好的选择是开始讨论 Codeplex forums .

关于c# - 属性类型更改时不更新鉴别器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18117475/

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