【问题标题】:Find out type with primary key given in Entity Framework using TPH使用 TPH 在 Entity Framework 中找出具有主键的类型
【发布时间】:2018-01-16 21:19:27
【问题描述】:

我有以下场景:

public abstract class Account
{
    public Guid PKey { get; set; } = Guid.NewGuid();    
    public string Owner { get; set; }
}

public class CheckingAccount : Account
{
    public int Fee { get; set; }
}

public class SavingAccount : Account
{
    public double InterestRate { get; set; }
}

我正在使用带有 Table per Hierarchy 的实体框架,因此数据库中将有一个表同时保存 CheckingAccount-Records 和 SavingAccount-Records 以及这个表将包含一个名为 Discriminator 的列,该列分别填充了值“CheckingAccount”或“SavingAccount”。

现在我想将一个主键(Guid)作为我的输入,并找出这个主键所属的记录类型。

我有一个给定的 Guid,想知道这个 Guid 的记录是 CheckingAccount-Record 还是 SavingAccount-Record。

我尝试过这样的事情:

using(MyContext ctx = new Context())
{
    CheckingAccount ca = ctx.CheckingAccount.Find(pKey);
    SavingAccount sa = ctx.SavingAccount.Find(pKey);

    if(ca != null)
    {
        Console.WriteLine("It's a CheckingAccount!");
    }
    else if(sa != null)
    {
        Console.WriteLine("It's a SavingAccount!");
    }
}

但是,这会导致 InvalidOperationException:当记录是 SavingAccount 时,它会说

“当请求 CheckingAccount 类型的实体时,找到的实体属于 SavingAccount 类型。”

当我调用第一个 Find() 方法时。

如何找出只给定主键的类型和它可能属于的两种类型?

【问题讨论】:

    标签: c# mysql .net entity-framework tph


    【解决方案1】:

    您可以通过基本实体DbSet 使用EF 多态查询。像这样的东西应该可以完成这项工作:

    var account = ctx.Set<Account>().Find(pKey);
    if(account is CheckingAccount)
    {
        Console.WriteLine("It's a CheckingAccount!");
    }
    else if (account is SavingAccount)
    {
        Console.WriteLine("It's a SavingAccount!");
    }
    

    【讨论】:

    • 是的,成功了!谢谢你!不幸的是,我的点赞不可见,因为我的声望太低了。
    【解决方案2】:

    您是否尝试过使用varobject 作为casa 的类型?

    试试这个:

    using(MyContext ctx = new Context())
    {
        object ca = ctx.CheckingAccount.Find(pKey);
        object sa = ctx.SavingAccount.Find(pKey);
    
        if(ca is CheckingAccount)
        {
            Console.WriteLine("It's a CheckingAccount!");
        }
        else if(sa is SavingAccount)
        {
            Console.WriteLine("It's a SavingAccount!");
        }
    }
    

    【讨论】:

    • 不幸的是,这也不起作用。 Find() 方法本身会引发异常,甚至在将结果分配给变量之前。
    • 这些类型是不是来自不同的sql表?
    • 不,所有记录都存储在一个名为“Account”的表中。该表包含一个名为“鉴别器”的列。在此列中,类型的名称(“CheckingAccount”或“SavingAccount”)在保存新记录时自动存储。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-19
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 2017-09-24
    相关资源
    最近更新 更多