实体框架 - 实体只读属性映射到相关列的列 [英] Entity Framework - Entity read-only property mapped to a column of related table

查看:127
本文介绍了实体框架 - 实体只读属性映射到相关列的列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个有趣的问题需要解决,但是虽然很常见,但实际框架看起来并不容易实现。有两个表:

I have interesting problem to solve but, although common, it looks like it's not easily achievable with Entity Framework. There are two tables:

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

玩家只能属于一个团队。使用TPT(DB首先),我们有两个类映射到这些表:

Player can belong only to one team. Using TPT (DB first), we have two classes mapped to those tables:

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

我想要实现的是属性IsProfessional on Player实体:

What I would like to achieve is property IsProfessional on Player 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;}
       **public bool IsProfessional{get;}** should be read-only
    }

是否可以配置映射方式IsProfessional属性可以在linq查询中使用?

Is it possible to configure mapping that way IsProfessional property can be used in linq queries?

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

并且每当玩家实体实现时填充该字段?

and to have that field populated every time Player entity is materialized?

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

已尝试使用:


  • 实体拆分。不可能,因为我想保持团队映射,因为关系不是1:1)

  • 将Player实体映射到数据库视图。不喜欢它,因为还有其他关系我需要的玩家实体。我知道可以手动创建它们,但从数据库更新edmx将重置ssdl。

  • Entity Splitting. Not possible because I want to keep Team mapping and because relationship is not 1:1)
  • Mapping Player entity to a db view. Didn't like it because there are other relationships Player entity has that I need. I know it is possible to create them manually, but updating edmx from database will reset ssdl.

谢谢

解决方案

根据Gert Arnold答案中的第二个选项,适合我需求的解决方案如下: / p>

Based on second option in Gert Arnold answer, solution that fits my needs is as follows:


  1. 我创建函数 GetIsProfessional (必须这样做,因为计算字段通常只能从自己的表格中进行)

  1. I create function GetIsProfessional (had to do it because computed fields normally can be made only from own table fields)

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


  • 我创建了 Player

    ALTER TABLE Players ADD [IsProfessional] AS dbo.GetIsProfessional(TeamId)
    


  • 使用db第一个方法,我jus从数据库更新模型就是这样,我可以查询该字段,并且在Player对象实现时预先填充。

  • As I'm using db first approach, I just update model from database and that's it, I can query on that field and it's pre populated when Player object is materialized.


    推荐答案

    这不能用EF完成。有些选项并不完全符合您的要求,但是几乎或多或少地接近:

    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. 创建属性 TeamPlayers 在您的上下文中返回包含该团队的玩家,以便您始终可以执行 player.Team.IsProfessional 甚至当上下文已经被放弃时。

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


  • 在数据库表中创建一个计算字段并映射到它与 DatabaseGeneratedOption.Computed

    中创建一个静态属性Player 返回访问 Team.IsProfessional 的表达式(需要包含生活环境或团队):

    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.

    这篇关于实体框架 - 实体只读属性映射到相关列的列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆