Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用继承策略将类型的实例转换为不同类型的实例_C#_Entity Framework Core - Fatal编程技术网

C# 使用继承策略将类型的实例转换为不同类型的实例

C# 使用继承策略将类型的实例转换为不同类型的实例,c#,entity-framework-core,C#,Entity Framework Core,我想问一下,如何更新以前存储为某个特定类型并且应该更新为另一个特定类型的行 假设我已将实体框架配置为使用每个层次的表继承策略。现在,假设我有这些课程: abstract class Package { public string SomeSharedValue { get; private set; } } class PublicPackage : Package { public int SomeProperty1 { get; private set; } publi

我想问一下,如何更新以前存储为某个特定类型并且应该更新为另一个特定类型的行

假设我已将实体框架配置为使用每个层次的
继承策略。现在,假设我有这些课程:

abstract class Package
{
   public string SomeSharedValue { get; private set; }
}

class PublicPackage : Package 
{
   public int SomeProperty1 { get; private set; }
   public Package TurnIntoPrivatePackage(int someProperty2)
   {
     return new PrivatePackage(someProperty2);
   }
}

class PrivatePackage : Package
{
   public int SomeProperty2 { get; private set; }
   public Package TurnIntoPublicPackage(int SomeProperty1)
   {
     return new PublicPackage(SomeProperty1);
   }
}
我以这样的方式配置了我的模型:

modelBuilder.Entity<Package>(m =>
{
    m.HasDiscriminator<int>("Type")
     .HasValue<PublicPackage>(1)
     .HasValue<PrivatePackage>(2);
});

好了,我已经有足够的想法了,你要完成什么

问题 您希望使用table per hierarchy来使用EF抽象2种不同类型的包,并且希望知道如何从一种包类型更改为另一种包类型,或者在数据库术语中,将discriminator值设置为新值并相应地更新对象

解决方案 不能直接或显式地将鉴别器设置为其他值。这里的github问题将进一步解释:

在上面的问题中,您可以使用他们的示例来解决这个问题,通过在模型生成器中设置它的元数据属性来显式地设置鉴别器。但不支持从一个物体到另一个物体的直接转化。看起来他们永远都不会支持它

您必须添加以下代码:

modelBuilder.Entity()
//EF核心版本2.0.0语法
.Property(“Type”).Metadata.AfterSaveBehavior=propertySaveBhavior.Save

我不确定我是否会走这条路,除非我处理的数据就其类型而言是静态的。这个问题会让我重新思考这个用例中的方法。

如果没有更多的代码,我不确定您在这里做什么。但听起来您是在实现代码重用的继承。在这种情况下,使用接口更有意义。这样,您就可以拥有相同的对象并公开所需的内容,而无需将“实例”转换为另一个子类实例。@PaulCarlton我有一个名为Package的实体。包可以作为私有包或公共包存在。两者都共享包中的一些字段,但也都有特定的字段,这些字段仅适用于该类型的包。用户可以动态地使包公开或私有。这就是为什么我把一些子类转换成另一个。这看起来像是使用接口的经典案例。您是否使用接口来定义公共/私有包的契约?另外,如果您不介意的话,我想看看您的包/私有/公共实现(您不需要共享ef模型迁移代码)。我将更新我的帖子,但我认为您误解了我的意图。实际上,我要问的是如何更新底层数据库行,因为如果我只调用
dbContext.UpdateAsync(modifiedPackage)
public async Task DoSomething(DbContext dbContext, Guid packageId){
   var package = dbContext.Packages.SingleOrDefaultAsync(f => f.Id == packageId);
   //now package is of type PublicPackage
   var updatedPackage = package.TurnIntoPrivatePackage(someValue)
   //updated package has the same Id and other values setted for private package right now but it's new (another) instance with the same id.
   dbContext.Update(updatedPackage); // Can I do this? should I detach the previous instance?
   await dbContext.SaveChangesAsync()
}