Entity Framework - Entity read-only property mapped to a column of related table

拈花ヽ惹草 提交于 2019-11-30 09:43:57
Gert Arnold

This can't be done with EF. There are some options that don't do exactly what you want, but get close more or less:

  1. Create a property TeamPlayers in your context that returns the players with the team included, so that you can always do player.Team.IsProfessional even when the context has already been diposed.

    public IQueryable<Player> TeamPlayers
    {
        get { return this.Players.Include("Team"); }
    }
    
  2. Create a calculated field in the database table and map to it with DatabaseGeneratedOption.Computed.

  3. Create a static property in Player that returns the expression that accesses Team.IsProfessional (requires a living context or team included):

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

I would prefer the calculated field, because it is always populated, so you can use it inside and outside the scope of a context.

Perseus

You can use System.ComponentModel.DataAnnotations.Schema.NotMappedAttribute to prevent mapping of the IsProfessional property like these:

// 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 ... */ } }
}

I used this attribute in EF5's Model First approach and I queried over DbContext/DbSet and ObjectContext/ObjectQuery without any exceptions. (100% tested)

kevin_fitz

What if you extend Player to have a property that pulls from Team?

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; } }
}

Of course, if you're worried about regenerating your EDMX, you can make it a partial:

public partial class Player
{
   public bool IsProfessional{ get { return Team.IsProfessional; } }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!