Mis*_* N. 6 entity-framework entity-framework-4 ef-database-first
我有一些有趣的问题需要解决,但是虽然很常见,但实际上看起来它并不容易实现.有两个表:
Player(Id,TeamId,FirstName,LastName)
Team(Id, Name, IsProfessional)
Run Code Online (Sandbox Code Playgroud)
玩家只能属于一个团队.使用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;}
}
Run Code Online (Sandbox Code Playgroud)
我想要实现的是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
}
Run Code Online (Sandbox Code Playgroud)
是否可以配置映射,以便在linq查询中使用IsProfessional属性?
var result= db.Players.Where(p=>p.IsProfessional==true);
Run Code Online (Sandbox Code Playgroud)
并且每次玩家实体实现时都填充该字段?
Player pl = db.Players.Where(p=>p.FirstName="Lionel").FirstOrDefault();
if(pl.IsProfessional)
{
//do something...
}
Run Code Online (Sandbox Code Playgroud)
已经尝试过:
谢谢
解
基于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
Run Code Online (Sandbox Code Playgroud)我在Player桌面上创建了计算字段
ALTER TABLE Players ADD [IsProfessional] AS dbo.GetIsProfessional(TeamId)
Run Code Online (Sandbox Code Playgroud)因为我正在使用数据库第一种方法,我只是从数据库更新模型,就是这样,我可以在该字段上查询,并且在实现Player对象时预先填充它.
这不能用EF完成.有些选项并不能完全符合您的要求,但可以或多或少地接近:
TeamPlayers在您的上下文中创建一个属性,该属性返回包含团队的玩家,这样player.Team.IsProfessional即使已经使用了上下文,您也可以随时执行此操作.
public IQueryable<Player> TeamPlayers
{
get { return this.Players.Include("Team"); }
}
Run Code Online (Sandbox Code Playgroud)在数据库表中创建一个计算字段并映射到它DatabaseGeneratedOption.Computed.
创建一个静态属性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)....
Run Code Online (Sandbox Code Playgroud)我更喜欢计算字段,因为它总是填充,因此您可以在上下文范围内外使用它.