http://www.entityframeworktutorial.net/code-first/entity-framework-code-first.aspx
Ef好的教程
Entity Framework的樂觀並發
http://www.cnblogs.com/Gyoung/archive/2013/01/18/2866649.html
附件:EntityFramework系列:MySql的RowVersion
EF里一對一、一對多、多對多關系的配置和級聯刪除
EntityFramework系列:Repository模式與單元測試
1. Nuget安裝好EF6.0.
2. 定義IDbContext , 定義context並實現
/// /// 提供對象列表的一切操作接口 /// public interface IDbContext : IDisposable { Database Database { get; } /// /// Get DbSet /// /// Entity type /// DbSet IDbSet Set() where TEntity : BaseEntity; /// /// Save changes /// /// int SaveChanges();
/// <summary> /// 繼承自DbContext, IDbContext, /// 為什么IDbContext接口里面的屬性和方法, 全部在DbContext里面有實現, 因此這里不需要做實現 /// </summary> public class NopObjectContext : DbContext, IDbContext { public NopObjectContext() : base("name=DefaultConnection") { //超時時常 ((IObjectContextAdapter)this).ObjectContext.CommandTimeout = 180; //這句代碼指定我們是自己手動生成數據庫 //Database.SetInitializer<XEngineContext>(null); } /// <summary> /// 覆蓋DbContext里面的Set屬性, 主要是為了自定義的BaseEntity. /// </summary> /// <typeparam name="TEntity">Entity type</typeparam> /// <returns>DbSet</returns> public new IDbSet<TEntity> Set<TEntity>() where TEntity : BaseEntity { return base.Set<TEntity>(); } protected override void OnModelCreating(DbModelBuilder modelBuilder) { //來自Nopcommerce里的動態加載所有的fluent api映射 dynamically load all configuration //System.Type configType = typeof(LanguageMap); //any of your configuration classes here //var typesToRegister = Assembly.GetAssembly(configType).GetTypes() modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();//去掉ef自建表的時候命名帶復數 modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); //全局刪掉級聯刪除, 因為不常用.移除這個默認約定,再在需要開啟級聯刪除的FluentAPI關系映射中用. WillCascadeOnDelete(true) 單獨開啟 var typesToRegister = Assembly.GetExecutingAssembly().GetTypes() .Where(type => !String.IsNullOrEmpty(type.Namespace)) .Where(type => type.BaseType != null && type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>)); foreach (var type in typesToRegister) { dynamic configurationInstance = Activator.CreateInstance(type); modelBuilder.Configurations.Add(configurationInstance); }; base.OnModelCreating(modelBuilder); }
下面來一個多對多的配置
下面是映射的map
如果用的聯合主鍵的話.
![]() |
![]() 這里的主鍵數量必須和表的主鍵數量相同 |
public class Student { public int ID { get; set; } public string Name { get; set; } public int SiteID { get; set; } public virtual ICollection Courses{get;set;} } public class Course{ public int ID{get;set;} public string Name { get; set; } public int SiteID { get; set; } public virtual ICollection Students { get; set; } } public class SCContext : DbContext { public SCContext() : base("name=DefaultConnection") { Database.SetInitializer(null); } protected override void OnModelCreating(DbModelBuilder modelBuilder) { //dynamically load all configuration //System.Type configType = typeof(LanguageMap); //any of your configuration classes here //var typesToRegister = Assembly.GetAssembly(configType).GetTypes() modelBuilder.Conventions.Remove(); modelBuilder.Entity().ToTable("Student").HasKey(x => new { x.ID, x.SiteID }) .Property(x => x.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); modelBuilder.Entity().ToTable("Course").HasKey(x => new { x.ID, x.SiteID }) .Property(x => x.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); //modelBuilder.Entity().Property(x => x.Name); modelBuilder.Entity().HasMany(x => x.Courses) .WithMany(x => x.Students) .Map(r => { r.ToTable("Student_Course_Mapping"); r.MapLeftKey(new string[]{"StudentID", "StudentSiteID"}); r.MapRightKey(new string[] { "CourseID", "CourseSiteID" }); }); base.OnModelCreating(modelBuilder); } }
下面是一對一
![]() 同樣在UserAccount里增加 ![]() |
![]() UserExt依賴於UserAccount |
最后是一對多
![]() 在UserAccount里增加 ![]() |
![]() 寫在UserAddressMap里. 這個表里有外鍵, 依賴於UserAccount. ![]() |
最后來一發表結構