EF Core默认情况下具有“代码优先的心态”,即应该以代码优先的方式使用,即使支持数据库优先的方法,它也仅是对现有数据库和产品进行反向工程而已。创建代码优先的表示形式。我的意思是,用“手动”代码(代码优先)创建的模型(POCO类),并从数据库(通过Scaffold-DbContext命令)生成的模型应该是相同的。
令人惊讶的是,EF Core官方文档显示出显着差异。下面是在代码中创建的模型的例子:https://ef.readthedocs.io/en/latest/platforms/aspnetcore/new-db.html这里是从现有的数据库逆向工程它的例子:HTTPS: //ef.readthedocs.io/en/latest/platforms/aspnetcore/existing-db.html
这是第一种情况下的实体类:
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public List<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public Blog Blog { get; set; }
}
这是第二种情况下的实体类:
public partial class Blog
{
public Blog()
{
Post = new HashSet<Post>();
}
public int BlogId { get; set; }
public string Url { get; set; }
public virtual ICollection<Post> Post { get; set; }
}
第一个示例是一个非常简单,非常明显的POCO类。它在文档的任何地方都显示(从数据库生成的示例除外)。但是,第二个示例具有一些附加功能:
我尝试过从数据库中构建模型(撰写本文时使用最新工具),它完全按照所示方式生成实体,因此这不是过时的文档问题。因此,官方工具会生成不同的代码,而官方文档则建议编写不同的(琐碎的)代码-无需局部类,虚拟成员,构造初始化等。
我的问题是,尝试在代码中构建模型,我应该如何编写代码?我喜欢使用ICollection而不是List,因为它更通用,但是除此之外,我不确定是否需要遵循文档或MS工具?我需要将它们声明为虚拟的吗?我需要在构造函数中对其进行初始化吗?等等...
我从旧的EF时代就知道虚拟导航属性允许延迟加载,但是EF Core甚至还不支持它,而且我不知道有任何其他用途。可能会影响性能吗?也许工具会尝试生成面向未来的代码,以便在实现延迟加载时,POCO类和上下文将能够对其进行支持?如果是这样,我可以抛弃它们,因为我不需要延迟加载(所有数据查询都封装在一个存储库中)吗?
很快,请帮助我理解为什么会有区别,以及在代码中构建模型时应使用哪种样式?
对于您提到的每一点,我都会尝试给出一个简短的答案
partial
类对于工具生成的代码特别有用。假设您要实现仅模型的派生属性。对于第一个代码,您可以在任何地方进行。对于数据库优先,如果您更新模型,则将重写类文件。因此,如果您想保留扩展代码,则要将其放置在托管模型之外的其他文件中-这是partial
帮助您扩展类而无需手动调整自动生成的代码的地方。
ICollection
绝对是一个合适的选择,即使是代码优先。如果没有排序语句,您的数据库可能将始终不支持定义的顺序。
构造函数初始化至少是一种便利...假设您在数据库方面有一个空集合,或者根本没有加载该属性。如果没有构造函数,则必须null
在代码中的任意点显式处理案例。无论你应该去List
或者HashSet
是我现在不能回答。
virtual
为数据库实体启用代理创建,这可以帮助两件事:如前所述,延迟加载和更改跟踪。代理对象可以使用设置器立即跟踪对虚拟属性的更改,而上下文中的普通对象需要在上进行检查SaveChanges
。在某些情况下,这可能会更有效(并非通常如此)。
virtual IDbSet
上下文条目使单元测试的测试模型上下文更容易设计。其他用例也可能存在。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句