一步步开发自己的博客 .NET版(9、从model first替换成code first 问题记录)
2016-05-31 08:34
453 查看
为什么要改用code first
用过code first的基本上都不会再想用回model first或是db first(谁用谁知道)。不要问我为什么不一开始就直接使用code first,因为那个时候我还不会(甚至还把model first当成了code first)。因为工作中使用的就是code first,且越用越习惯,越用越喜欢。
原因如果:
再也用为每次生成那个笨重的edmx文件性急了
再也不用当心保存tt文件而丢失特性、注销、扩展方法了
再也不用为了使用微软的验证插件非得写Metadata文件了
再也不用为了扩展tt文件生成的实体类去写(partial)部分类了。
再也不用为了生成满足自己需要的实体而去修改那些坑爹的tt文件里面的语法代码了(如:默认每个实体继承一个父类)
再也不用为了查找edmx文件打不开,去编辑庞大的edmx文件中找那些坑爹的错误了。
等等还有些暂时没想到的....
说改就改
修改前实体:db first(由tt文件生成)public class BlogDbContext : DbContext { public BlogDbContext() : base("HiBlogsTest") { } protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); var entityBlogUser = modelBuilder.Entity<BlogUser>(); entityBlogUser.HasMany(p => p.BlogInfos).WithRequired(t => t.BlogUser) .Map(m => m.MapKey("BlogUserId")).WillCascadeOnDelete(false); //与上面等效 //modelBuilder.Entity<BlogInfo>().HasRequired(p => p.BlogUser).WithMany(t => t.BlogInfos) //以BlogUser为主表(BlogUserInfo为从表,建立外键) entityBlogUser.HasRequired(p => p.BlogUserInfo).WithRequiredPrincipal(t => t.BlogUser) .Map(m => m.MapKey("BlogUserId")).WillCascadeOnDelete(false); //等效于HasRequired(p => ).WithOptional(i => ); ////以BlogUserInfo为主表(BlogUser为从表,建立外键) //modelBuilder.Entity<BlogUser>().HasRequired(p => p.BlogUserInfo).WithRequiredDependent(t => t.BlogUser) //.Map(m => m.MapKey("BlogUserId")).WillCascadeOnDelete(false); //等效于 HasOptional(p => ).WithRequired(i => ); entityBlogUser.HasMany(p => p.BlogTags).WithRequired(t => t.BlogUser) .Map(m => m.MapKey("BlogUserId")).WillCascadeOnDelete(false); entityBlogUser.HasMany(p => p.BlogTypes).WithRequired(t => t.BlogUser) .Map(m => m.MapKey("BlogUserId")).WillCascadeOnDelete(false); entityBlogUser.HasMany(p => p.BlogComments).WithRequired(t => t.BlogUser) .Map(m => m.MapKey("BlogUserId")).WillCascadeOnDelete(false); var entityBlogInfo = modelBuilder.Entity<BlogInfo>(); entityBlogInfo.HasMany(p => p.BlogTags).WithMany(t => t.BlogInfos) .Map(m => m.ToTable("BlogInfo_BlogTag")); entityBlogInfo.HasMany(p => p.BlogTypes).WithMany(t => t.BlogInfos) .Map(m => m.ToTable("BlogInfo_BlogType")); entityBlogInfo.HasMany(p => p.BlogComments).WithRequired(t => t.BlogInfo) .Map(m => m.MapKey("BlogInfoId")).WillCascadeOnDelete(false); entityBlogInfo.HasMany(p => p.BlogReadInfos).WithRequired(t => t.BlogInfo) .Map(m => m.MapKey("BlogInfoId")).WillCascadeOnDelete(false); } public DbSet<BlogInfo> BlogInfos { get; set; } public DbSet<BlogComment> BlogComments { get; set; } public DbSet<BlogReadInfo> BlogReadInfos { get; set; } public DbSet<BlogTag> BlogTags { get; set; } public DbSet<BlogType> BlogTypes { get; set; } public DbSet<BlogUser> BlogUsers { get; set; } public DbSet<BlogUserInfo> BlogUserInfos { get; set; } }
View Code
然后重新命令:Add-Migration blogs 再执行 update-database
完美,表结构过来了。表关系过来了。(接下来就是该代码了,因为表名做了小的改动,字段也做了少许调整所以改的东西还真不少。整整改了一天时间。)
现在回过头来想想,之前是先model first之后小许改动就用的db first。以前怎么没有遇到过(将 FOREIGN KEY 约束 'FK_dbo.BlogInfo_dbo.BlogUser_BlogUserId' 引入表 'BlogInfo' 可能会导致循环或多重级联路径。请指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。
无法创建约束。请参阅前面的错误消息。)这个错误。好奇心驱使,觉得看看以前的代码的edmx是怎么管理这种关系的。
很惊奇的发现,完全没有问题。于是,不死心看看数据库里面是不是有什么蹊跷。
搜噶,原来如此。通过model first生成的主外键关系默认就没有设计联级删除,而code first默认设置就是联级删除。
以上内容,都是我胡说八道。谢谢您的阅读,希望对您有那么一点点作用。
Hi-Blogs源码地址:http://git.oschina.net/zhaopeiym/Hi-Blogs
最近因为工作实在太慢,开源博客长久没有更新。今天突然来回翻了好几遍,发现半年前的自己写的代码是如此的不堪入目。
今天仅仅只是把db first改成了code first,发霉的代码我还得找个时间好好重构重构。
首发地址:/article/11828231.html
相关文章推荐
- js中控制图片的循环播放
- CodeForces 24B F1 Champions(排序)
- CodeForces 24B F1 Champions(排序)
- 构建之法阅读笔记06
- 大话设计模式-第03章 拍摄UFO-单一职责原则
- 如何找出数组中只出现一次的数字
- 百度地图开发,实现鼠标悬浮事件以及点击事件
- CodeForces 24A Ring road(dfs)
- (十二)boost库之多线程高级特性
- CodeForces 24A Ring road(dfs)
- (十二)boost库之多线程高级特性
- VMware vSphere常见问题汇总(二十三)
- 2016SDAU课程练习三1006
- (十一)boost库之多线程间通信
- (十一)boost库之多线程间通信
- No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK
- (九)boost库之文件处理filesystem
- (十)boost库之多线程
- (八)boost库之异常处理
- (九)boost库之文件处理filesystem