EF Code First 使用反射加载程序集中的Fluent API配置文件
2017-06-01 17:07
579 查看
在C#/.NET的Entity Framework Code First开发中,我们会涉及到关于数据库连接的配置类,该类会继承至DbContext类,其主要目的是配置数据库的连接字符串或者名字以及相关的其他参数,如果我们需要重写DbContext的OnModelCreating()的方法并加载实体的Fluent API配置文件的话,一般可以使用如下的方法:
其中UserConfiguration即为User类对应的Fluent API配置文件类,该类继承至:EntityTypeConfiguration类,为了方面大家阅读起来更容易,我把UserConfiguration的配置代码贴出来,如下:
其中EntityTypeConfiguration中的User为实体类,具体的配置选项可根据自己的需求来定制。 写到这里,我们以上表现的内容还没有和本文的主题产生联系。那么,我们现在来看一个问题,即:在项目中每增加一个实体类对应的EntityTypeConfiguration的配置文件,我们就需要在OnModelCreating的重写方法中新添加一行对应的配置行:
这样做肯定是没有问题的,但这样的做法效率太低,而且不好维护。那么,下面我们就利用反射来动态加载Fluent API文件到OnModelCreating的重写方法中去,具体的实现代码如下:
这样,我们不管以后写多少个Fluent API的配置文件,程序都会自动为我们加载,是不是很方便的一个小技巧呢?
调用就更简单了,如:
其中的Enabled即为user对应实体类的一个属性。
modelBuilder.Configurations.Add(new UserConfiguration());
其中UserConfiguration即为User类对应的Fluent API配置文件类,该类继承至:EntityTypeConfiguration类,为了方面大家阅读起来更容易,我把UserConfiguration的配置代码贴出来,如下:
public class UserConfiguration : EntityTypeConfiguration<User> { public UserConfiguration() { Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); Property(x => x.Guid).HasMaxLength(50).IsRequired(); Property(x => x.LoginName).HasMaxLength(50).IsRequired().HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute("IX_LoginName", 1) { IsUnique = true })); Property(x => x.Password).HasMaxLength(80).IsRequired(); Property(x => x.DisplayName).HasMaxLength(80).IsRequired(); Property(x => x.EmailAddress).HasMaxLength(120).IsRequired(); Property(x => x.FirstName).HasMaxLength(80); Property(x => x.LastName).HasMaxLength(80); Property(x => x.CreatedBy).HasMaxLength(80); Property(x => x.ModifiedBy).HasMaxLength(80); Property(x => x.LatestIp).HasMaxLength(36); } }
其中EntityTypeConfiguration中的User为实体类,具体的配置选项可根据自己的需求来定制。 写到这里,我们以上表现的内容还没有和本文的主题产生联系。那么,我们现在来看一个问题,即:在项目中每增加一个实体类对应的EntityTypeConfiguration的配置文件,我们就需要在OnModelCreating的重写方法中新添加一行对应的配置行:
modelBuilder.Configurations.Add(new Configuartion());
这样做肯定是没有问题的,但这样的做法效率太低,而且不好维护。那么,下面我们就利用反射来动态加载Fluent API文件到OnModelCreating的重写方法中去,具体的实现代码如下:
protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); //modelBuilder.Configurations.Add(new UserConfiguration()); var typesToRegister = Assembly.GetExecutingAssembly().GetTypes() .Where(x => !string.IsNullOrEmpty(x.Namespace)) .Where(x => x.BaseType != null && x.BaseType.IsGenericType && x.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>)); foreach (var type in typesToRegister) { dynamic configurationInstance = Activator.CreateInstance(type); modelBuilder.Configurations.Add(configurationInstance ); } }
这样,我们不管以后写多少个Fluent API的配置文件,程序都会自动为我们加载,是不是很方便的一个小技巧呢?
EF Code First Repository泛型类中只更新实体的指定字段(属性)
在C#的Entity Framework ORM中,如果使用context.Entry(T).State=EntityState.Modified;来更新实体的话,整个实体的字段都将被更新。那么,如果我们在开发中只需要更新部分指定的字段应该如何操作呢?一种简单的实现方式就是使用表达式树作为更新方法的参数,然后使用Property(T).IsModified=true来对指定字段进行更新,具体的代码如下:public virtual int Update(T entity, params Expression<Func<T, object>>[] updatedProperties) { var dbEntityEntry = dataContext.Entry(entity); if (updatedProperties.Any()) { foreach (var property in updatedProperties) { dbEntityEntry.Property(property).IsModified = true; } } else { foreach (var property in dbEntityEntry.OriginalValues.PropertyNames) { var original = dbEntityEntry.OriginalValues.GetValue<object>(property); var current = dbEntityEntry.CurrentValues.GetValue<object>(property); if (original != null && !original.Equals(current)) { dbEntityEntry.Property(property).IsModified = true; } } } return dataContext.SaveChanges(); }
调用就更简单了,如:
_userRepository.Update(user,x=>x.Enabled);
其中的Enabled即为user对应实体类的一个属性。
相关文章推荐
- 在使用EFCodeFirst中出现类型“System.Data.Objects.ObjectContext”在未被引用的程序集中定义的解决方案
- 在使用EFCodeFirst中出现类型“System.Data.Objects.ObjectContext”在未被引用的程序集中定义的解决方案
- (1) 写一个 Properties 格式的配置文件,配置类的完整名称。 * (2) 写一个程序,读取这个 Properties 配置文件,获得类的完整名称并加载这个类,用 反射 的方式运行
- java反射,类加载器以及配置文件的结合使用
- EF CodeFirst 使用T4模板 生成文件
- Java 反射将配置文件数据加载到对象属性中Reflect与Properties使用
- Code First for Mysql 错误:未为提供程序“MySql.Data.MySqlClient”找到任何 MigrationSqlGenerator。请在目标迁移配置类中使用 SetSql
- 使用反射机制动态加载配置文件
- EF6 调用SQLite(适用于code first,非code first参考官方配置文件)
- 将所有程序设置XML集中到一个单独XML配置文件的方法:使用appSettings元素的configSource元素
- Spring中使用classpath加载配置文件浅析[转]
- 一起谈.NET技术,在ASP.NET MVC3中使用EFCodeFirst 1.0
- 使用java程序读取配置文件中的相关属性值-asp.net关注
- Entity Framework Code First使用者的福音 --- EF Power Tool使用记之一(转)
- 自己来控制EntityFramework4.1 Code-First,强大的EF多种加载方式
- 创建 loggingConfiguration 的配置节处理程序时出错: 未能加载文件或程序集“Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=
- 使用类加载器加载配置文件
- Entity Framework Code First使用者的福音 --- EF Power Tool使用记之一
- Spring中使用classpath加载配置文件浅析
- Android使用主题配置文件,去掉程序启动界面的短暂黑屏。