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. |
最后来一发表结构