我有一个有趣的问题要解决,但虽然很常见,但它看起来并不容易通过 Entity Framework 实现。有两个表:
Player(Id,TeamId,FirstName,LastName)
Team(Id, Name, IsProfessional)
玩家只能属于一支球队。使用 TPT(DB first),我们有两个类映射到这些表:
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
}
是否可以在 linq 查询中使用 IsProfessional 属性来配置映射?
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)
- 将播放器实体映射到数据库视图。不喜欢它,因为玩家实体还有我需要的其他关系。我知道可以手动创建它们,但是从数据库更新 edmx 会重置 ssdl。
谢谢
解决方案
基于 Gert Arnold 回答中的第二个选项,适合我需要的解决方案如下:
我创建函数
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
Player
我在表上创建了计算字段ALTER TABLE Players ADD [IsProfessional] AS dbo.GetIsProfessional(TeamId)
当我使用 db first 方法时,我只是从数据库中更新模型,仅此而已,我可以在该字段上进行查询,并在 Player 对象物化时预先填充它。