9

解決すべき興味深い問題がありますが、一般的ではありますが、Entity Framework では簡単に達成できないようです。次の 2 つのテーブルがあります。

Player(Id,TeamId,FirstName,LastName)
Team(Id, Name, IsProfessional)

プレイヤーは 1 つのチームにのみ所属できます。TPT (DB ファースト) を使用すると、これらのテーブルに 2 つのクラスがマップされます。

public class Player
{
   public int Id{get;set;}
   public int TeamId{get;set;}
   public string FirstName{get; set;}
   public string LastName{get; set;}
   public Team Team{get;set;}
}

public class Team
{ 
   public int Id{get; set;}
   public string Name{get;set;}
   public bool IsProfessional{get;set;}
   public IEnumerable<Player> Players{get;}
}

私が達成したいのは、Player エンティティの IsProfessional プロパティです。

public class Player
    {
       public int Id{get;set;}
       public int TeamId{get;set;}
       public string FirstName{get; set;}
       public string LastName{get; set;}
       public Team Team{get;set;}
       **public bool IsProfessional{get;}** should be read-only
    }

IsProfessional プロパティを linq クエリで使用できるようにマッピングを構成することは可能ですか?

var result= db.Players.Where(p=>p.IsProfessional==true);

Player エンティティが実体化されるたびにそのフィールドにデータが入力されるようにするには?

Player pl = db.Players.Where(p=>p.FirstName="Lionel").FirstOrDefault();
if(pl.IsProfessional)
{
//do something...
}

すでに試しました:

  • エンティティ分割。チーム マッピングを維持したいため、また関係が 1:1 ではないため、不可能です)
  • Player エンティティを db ビューにマッピングします。Playerエンティティには他にも必要な関係があるため、好きではありませんでした。手動で作成できることはわかっていますが、データベースから edmx を更新すると ssdl がリセットされます。

ありがとう

解決

Gert Arnold の回答の 2 番目のオプションに基づいて、私のニーズに合ったソリューションは次のとおりです。

  1. 関数を作成しますGetIsProfessional(計算フィールドは通常、独自のテーブル フィールドからしか作成できないため、実行する必要がありました)

    CREATE FUNCTION [dbo].[GetIsProfessional](@teamId as INT)
    RETURNS bit
    
    BEGIN
    
    DECLARE @isProfi AS bit
    
    SELECT @isProfi = IsProfessional
    FROM Teams
    WHERE Id = @teamId
    
    RETURN @isProfi
    
    END
    
  2. Playerテーブルに計算フィールドを作成しました

    ALTER TABLE Players ADD [IsProfessional] AS dbo.GetIsProfessional(TeamId)
    
  3. 私はdb firstアプローチを使用しているので、データベースからモデルを更新するだけで、そのフィールドでクエリを実行でき、Playerオブジェクトが実体化されると事前に入力されます。

4

3 に答える 3

10

これは EF では実行できません。希望どおりに動作しないオプションがいくつかありますが、多かれ少なかれそれに近づきます。

  1. TeamPlayersチームが含まれているプレーヤーを返すプロパティをコンテキストに作成しplayer.Team.IsProfessionalて、コンテキストが既に破棄されている場合でもいつでも実行できるようにします。

    public IQueryable<Player> TeamPlayers
    {
        get { return this.Players.Include("Team"); }
    }
    
  2. データベース テーブルに計算フィールドを作成し、 でマップしますDatabaseGeneratedOption.Computed

  3. Playerアクセスする式を返す静的プロパティを作成しますTeam.IsProfessional(生きているコンテキストまたはチームが含まれている必要があります)。

    public static Expression<Func<Player, bool>> IsProfessional
    {
        get { return p => p.Team.IsProfessional; }
    }
    ...
    db.Players.Where( p=> p.FirstName="Lionel").Where(Player.IsProfessional)....
    

計算フィールドは常に入力されているため、コンテキストの範囲内外で使用できるため、計算フィールドをお勧めします。

于 2012-10-10T10:33:45.217 に答える
0

チームからプルするプロパティを持つようにPlayerを拡張するとどうなりますか?

public partial class Player
{
   public int Id{get;set;}
   public int TeamId{get;set;}
   public string FirstName{get; set;}
   public string LastName{get; set;}
   public Team Team{get;set;}

   public bool IsProfessional{ get { return Team.IsProfessional; } }
}

もちろん、EDMXの再生成が心配な場合は、部分的にすることができます。

public partial class Player
{
   public bool IsProfessional{ get { return Team.IsProfessional; } }
}
于 2012-10-09T20:47:13.270 に答える
0

次のようなプロパティSystem.ComponentModel.DataAnnotations.Schema.NotMappedAttributeのマッピングを防ぐために使用できます。IsProfessional

// Mapped part of entity
public class Player
{
    public int Id { get; set; }
    public int TeamId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Team Team { get; set; }
}

// Unmapped part of entity
using System.ComponentModel.DataAnnotations.Schema;
...
public partial class Player
{
    [NotMapped()]
    public bool IsProfessional { get { /* ... IsProfessional calculation logic comes here ... */ } }
}

EF5's Model First私はアプローチでこの属性を使用しDbContext/DbSetObjectContext/ObjectQuery例外なくクエリを実行しました。(100% テスト済み)

于 2013-06-05T00:20:42.043 に答える