18

Entity Framework 4 CTP5 Code First とこの例の使用

識別子の値にアクセスできますか?

のような投影で使用したいと思います

context.BillingDetails.Select(x => new { Number = x.Number, DiscrimitatorValue = /* how do I get the discriminator value? */ });

この投稿から、ディスクリミネーターをプロパティにマップできないことは理解していますが、それにアクセスする他の方法はありますか?

4

7 に答える 7

24

これについてはゲームに遅れているかもしれませんが、現在の型の名前を返す基本クラスに getter プロパティを追加しただけです。

public string DiscriminatorValue {
    get {
        return this.GetType().Name;
    }
}

デフォルトでは、EF は Discriminator フィールドにこの同じ値を使用するため、それらは一致します。

于 2013-06-11T16:44:39.323 に答える
13

EF Core 2.1 (以前のバージョンは確認していません) ではDiscriminator、基本抽象クラスにプライベート セット プロパティを追加するだけで十分です。適切な値でマッピングされます。

public abstract class Entity
{
    public int Id { get; set; }
    public string Discriminator { get; private set; }
}

EF 自体は、適切な識別子の値をデータベースに自動的に挿入し、読み取り時にそれをオブジェクトに自動的に設定します。

于 2018-07-26T11:59:42.653 に答える
8

彼の投稿のコメントでMortezaManaviからさらに情報を得た後、簡単な答えはノーです

識別子列はCodeFirstによって内部的に使用され、継承マッピングの観点からその値を読み書きできないことに注意する必要があります。

識別子にアクセスするにはSqlQuery、データベースに対してを実行するか、マッピング戦略を変更する必要があります。

于 2011-01-04T14:42:21.717 に答える
5

Reason aside, I recently ran into the same problem but believe this is still relevant for v4 of the EF Framework.

First, create a view which selects the discriminator value into two columns.

create view dbo.vw_BillingDetail
as
    select BillingDetailId, DiscriminatorValue, DiscriminatorValue as DiscriminatorValue2 from dbo.BillingDetail
go

Secondly, map the view to your entity during context creation:

modelBuilder
    .Entity<BillingDetail>()
    .HasKey(n => n.BillingDetailId)
    .Map(map =>
    {
        map.ToTable("vw_Person");
    })

Thirdly, define your discriminator mapping for your derived class using one of the columns in your view:

.Map<MyDerivedBillingDetail>(map =>
{
    map.Requires("DiscriminatorValue2").HasValue("YourValue");
})

Finally, define a getter and a private setter for the other discriminator column in your view with the DatabaseGenerated annotation set as Computed to prevent EF from updating/inserting for this field:

class BillingDetail
{
    public BillingDetailId { get; set; }

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DiscriminatorValue { get; private set; }
}

You can change the private setter to be protected and set this value explicitly during the construction of your derived entities so that the discriminator has a value prior to being persisted:

class MyDerivedBillingDetail : BillingDetail
{
    public MyDerivedBillingDetail()
    {
        this.DiscriminatorValue = "MyValue";
    }
}
于 2015-12-10T18:08:23.890 に答える
1

代わりに次のクエリを使用してみませんか?

 var q = con.BillingDetails.OfType<BankAccount>().ToList();
于 2010-12-24T14:12:17.737 に答える
0

EF Core の識別子に指定した名前のプロパティを追加できます。例:

DBContext で:

...HasDiscriminator<string>("Type")..

基本クラスで次のことを行います。

public string Type { get; private set; }
于 2021-07-23T11:49:22.207 に答える