EF

时间:2017-12-06 13:00:03

标签: c# sql sql-server database entity-framework

我在尝试查看我可以用它做什么时,一直在讨论实体框架代码。 我测试过的一个场景是尝试复制以下数据库架构:

表:

  • 播放器
  • 管理器

enter image description here

人员表包含基本数据名称,年龄等。

播放器表仅保存与播放器相关的信息:currentclubId,positionId等 玩家基本细节将通过与玩家ID和PersonId上的Person表的1:1关系提供。

管理员表非常类似于播放器表与管理员标识和人员ID上的人员表保持1:1的关系。

这种模式背后的理念是,一个人在整个职业生涯中都可以成为玩家和经理,我希望避免重复基本的细节。

我的问题是EF使用Person属性生成玩家模型。

public class Player {
    public Person Person {get;set;}
    .....    
}

因此,要获得玩家的名字,您必须调用Player.Person.FirstName。 这个流程在开始时很好,但是我开始看到Player和Manager查询的性能问题,因为它们必须从两个表中获取。

有没有什么办法可以重构这个模式来提高性能而不违反要求?

2 个答案:

答案 0 :(得分:1)

根据您提供的图表中的架构,我希望有类似......

的内容
public class Person
{   
   [Key]
   public int PersonId {get;set;}

   [ForeignKey("Player")]
   public int player {get;set;} // make this int? if a person can optionally be a player

   public virtual Player Player {get;set;}
   ...
}

然后,您将为person对象上的manager属性重复此属性模型。 完成此操作后,在查询数据库时,您应该使用。Include()以避免在延迟加载情况下将递归子查询返回到数据库"。

例如:

var allJoes = Db.Persons
   .Where(p => p.Name.Contains("Joe"))
   .Include(p => p.Player)
   .Include(p => p.Manager);

您可以选择添加子选择,以便从数据库中仅从该数据中提取所需的字段。

var joePieces = allJoes
    .Select(j => new { j.Name, j.Player.PlayerId, j.Manager.ManagerId });

最终结果是......

的执行
var results = joePieces.ToArray();

答案 1 :(得分:1)

由于您将每个类放在一个单独的表中,因此总会有3个表。因此,在任何查询中,您都会有join语句,这会导致您提到的性能问题。实际上,您定义的域不需要在表中分离。它们只是一个具有一些细微差别的对象。因此,将表合并为一个是一个好主意,并避免join个查询。要做到这一点,你有一些选择:

  1. 使用继承:让PlayerManager继承自Person并使用TBH方法。

  2. 使用ComplexType:制作PlayerManager复杂类型(EF会看到它们就像intstringenum等)。

  3. 在这两种情况下,所有3种类型都只有一个表格;并且根本不会有join