我在尝试查看我可以用它做什么时,一直在讨论实体框架代码。 我测试过的一个场景是尝试复制以下数据库架构:
表:
人员表包含基本数据名称,年龄等。
播放器表仅保存与播放器相关的信息: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查询的性能问题,因为它们必须从两个表中获取。
有没有什么办法可以重构这个模式来提高性能而不违反要求?
答案 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
个查询。要做到这一点,你有一些选择:
使用继承:让Player
和Manager
继承自Person
并使用TBH方法。
使用ComplexType:制作Player
和Manager
复杂类型(EF会看到它们就像int
,string
,enum
等)。
在这两种情况下,所有3种类型都只有一个表格;并且根本不会有join
。