• EF 学习笔记


    1、一次性添加映射

     1     public class EntityDbContext : DbContext 
     2     {  
     3         public EntityDbContext()
     4             : base("name=test2")
     5         { }
     6 
     7 
     8         /// <summary>
     9         /// 通过反射一次性将表进行映射
    10         /// </summary>
    11         /// <param name="modelBuilder"></param>
    12         protected override void OnModelCreating(DbModelBuilder modelBuilder)
    13         {
    14            
    15             var typesRegister = Assembly.GetExecutingAssembly().GetTypes()
    16                 .Where(type => !(string.IsNullOrEmpty(type.Namespace))).Where(type => type.BaseType != null && type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
    17             foreach (var type in typesRegister)
    18             {
    19                 dynamic configurationInstance = Activator.CreateInstance(type);
    20                 modelBuilder.Configurations.Add(configurationInstance);
    21             }
    22 
    23         }
    24     }
    View Code
     1     public class StudentMap : EntityTypeConfiguration<Student>
     2     {
     3         public StudentMap()
     4         {
     5             ToTable("Student");
     6             HasKey(d => d.ID);
     7           
     8             //HasRequired(p => p.Course).WithRequiredDependent(i => i.Student);           
     9             //HasRequired(p => p.Course).WithOptional(i => i.Student);
    10 
    11             HasRequired(p => p.Course).WithRequiredPrincipal(p => p.Student);
    12             HasOptional(p => p.Course).WithRequired(p => p.Student);
    13 
    14             /*
    15              对于上述映射关系不太理解的话可以去上述给出链接文章。我只说明怎么去很好的理解这两组的意思,第一组 WithRequiredDependent 和第二组
    16              WithRequiredPrincipal 一个是Dependent是依赖的意思说明后面紧接着的Student是依赖对象,而前面的Course是主体,而Principal
    17              首先的意思,说明后面紧接着的是Student是主体,而Course是依赖对象。很显然在这个关系中课程是依赖学生的。所以映射选第二组  
    18             */
    19         }
    20     }
    StudentMap

    2、延迟加载必须满足三个条件:

    1. this.Configuration.ProxyCreationEnabled = true;
    2. this.Configuration.LazyLoadingEnabled = true;
    3. 导航属性修饰符必须为Virtual

    3、映射private/protected/internal属性:

    1     public class Student
    2     {
    3         public string Id { get; set; }
    4         public string Name { get; set; }
    5         private string TestPrivate { get; set; }
    6         internal string TestInternal { get; set; }
    7         protected string TestProtected { get; set; }
    8
     1   public class BreakAwayContext : DbContext
     2     {
     3         public BreakAwayContext()
     4             : base("name=BreakAwayContext")
     5         {
     6             this.Configuration.LazyLoadingEnabled = false;//对所有实体关闭惰性加载
     7             this.Configuration.ProxyCreationEnabled = false;//禁止创建代理
     8 
     9             DbInterception.Add(new NLogCommandInterceptor());
    10         }
    11 
    12         protected override void OnModelCreating(DbModelBuilder modelBuilder)
    13         {
    14             ////<EF 6.0
    15             //modelBuilder.Entities().Configure(c =>
    16             //{
    17             //    var nonPublicProperties = c.ClrType.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance);
    18 
    19             //    foreach (var p in nonPublicProperties)
    20             //    {
    21             //        c.Property(p).HasColumnName(p.Name);
    22             //    }
    23             //});
    24             //EF 6.0
    25             modelBuilder.Types().Configure(d =>
    26             {
    27                 var nonPublicProperties = d.ClrType.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance);
    28                 foreach (var p in nonPublicProperties)
    29                 {
    30                     d.Property(p).HasColumnName(p.Name);
    31                 }
    32             });
    33             modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    34         }
    35 
    36         public DbSet<Student> Students { get; set; }
    37 
    38     }

    4、各种查询:

    条件查询

    1     var sql = "select ID, Name, Age from Student where Name = @Name and Age = @Age";
    2 
    3      ctx.Database.SqlQuery<Student>(
    4                 sql, 
    5                 new SqlParameter("@Name", Name),
    6                 new SqlParameter("@Age", Age));

    非实体查询

    ctx.Database.SqlQuery<int>("select Age from Student").ToList();

     执行存储过程

    ctx.Database.SqlQuery<Student>("dbo.GetList").ToList();
     var param = new SqlParameter("Age", 5);
     var list = ctx.Database.SqlQuery<Student>("dbo.GetList @Age", param).ToList();
    
    /*查询出的所有列必须对应返回实体中的所有字段,缺一不可,否则报错!在调用存储过程中,如果数据库是Sql 2005要在存储过程名称前加上 EXEC,否则报错*/
           var name = new SqlParameter { ParameterName = "Name", Value = Name };
                var currentpage = new SqlParameter { ParameterName = "PageIndex", Value = currentPage };
                var pagesize = new SqlParameter { ParameterName = "PageSize", Value = pageSize };
                var totalcount = new SqlParameter { ParameterName = "TotalCount", Value = 0, Direction = ParameterDirection.Output };
    
                var list = ctx.Database.SqlQuery<Student>("Myproc @Name, @PageIndex, @PageSize, @TotalCount output",
            name, currentpage, pagesize, totalcount);
    
                totalCount = (int)totalcount.Value;  /*获得要输出参数totalcount的值*/
     1 public IList<TEntity> ExecuteStoredProcedureList<TEntity>(string commandText, params object[] parameters) where TEntity : class
     2         {
     3             if (parameters != null && parameters.Length > 0)
     4             {
     5                 for (int i = 0; i <= parameters.Length - 1; i++)
     6                 {
     7                     var p = parameters[i] as DbParameter;
     8                     if (p == null)
     9                         throw new Exception("Not support parameter type");
    10 
    11                     commandText += i == 0 ? " " : ", ";
    12 
    13                     commandText += "@" + p.ParameterName;
    14                     if (p.Direction == ParameterDirection.InputOutput || p.Direction == ParameterDirection.Output)
    15                     {
    16 
    17                         commandText += " output";
    18                     }
    19                 }
    20             }
    21 
    22             var result = this.Database.SqlQuery<TEntity>(commandText, parameters).ToList();
    23 
    24  
    25             bool acd = this.Configuration.AutoDetectChangesEnabled;
    26             
    27             try
    28             {
    29                 this.Configuration.AutoDetectChangesEnabled = false;
    30 
    31                 for (int i = 0; i < result.Count; i++)
    32                     result[i] = this.Set<TEntity>().Attach(result[i]);
    33             }
    34             finally
    35             {
    36                 this.Configuration.AutoDetectChangesEnabled = acd;
    37             }
    38 
    39             return result;
    40         }
    调用存储过程封装
    var list = ctx.ExecuteStoredProcedureList<Student>("Myproc", pageindex, pagesize, totalcount);

    5、EF在查询之前进行操作来忽略尾随空格

     1     public class EFConfiguration : DbConfiguration
     2     {
     3         public EFConfiguration()
     4         {
     5             AddInterceptor(new StringTrimmerInterceptor());
     6         }
     7     }
     8     public class StringTrimmerInterceptor : IDbCommandTreeInterceptor
     9     {
    10         public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext)
    11         {
    12             if (interceptionContext.OriginalResult.DataSpace == DataSpace.SSpace)
    13             {
    14                 var queryCommand = interceptionContext.Result as DbQueryCommandTree;
    15                 if (queryCommand != null)
    16                 {
    17                     var newQuery = queryCommand.Query.Accept(new StringTrimmerQueryVisitor());
    18                     interceptionContext.Result = new DbQueryCommandTree(
    19                         queryCommand.MetadataWorkspace,
    20                         queryCommand.DataSpace,
    21                         newQuery);
    22                 }
    23             }
    24         }
    25 
    26         private class StringTrimmerQueryVisitor : DefaultExpressionVisitor
    27         {
    28             private static readonly string[] _typesToTrim = { "nvarchar", "varchar", "char", "nchar" };
    29 
    30             public override DbExpression Visit(DbNewInstanceExpression expression)
    31             {
    32                 var arguments = expression.Arguments.Select(a =>
    33                 {
    34                     var propertyArg = a as DbPropertyExpression;
    35                     if (propertyArg != null&& _typesToTrim.Contains(propertyArg.Property.TypeUsage.EdmType.Name))
    36                     {
    37                         return EdmFunctions.Trim(a);
    38                     }
    39  
    40                     return a;
    41                 });
    42  
    43                 return DbExpressionBuilder.New(expression.ResultType, arguments);
    44             }
    45         }
    46     }
    EF在查询之前进行操作来忽略尾随空格

    6、扩展方法

     1     public static class EFExt
     2     {
     3         /// <summary>
     4         /// 获得实体的所有键的名称
     5         /// </summary>
     6         /// <param name="ctx"></param>
     7         /// <param name="entity"></param>
     8         /// <returns></returns>
     9         static string[] GetKeyNames(this DbContext ctx, Type entity)
    10         {
    11             var metadata = ((IObjectContextAdapter)ctx).ObjectContext.MetadataWorkspace;
    12 
    13             /*获得CLR type集合和medata OSpace之间的映射*/
    14             var objItemCollection = (ObjectItemCollection)metadata.GetItemCollection(DataSpace.OSpace);
    15 
    16             /*根据所给的CLR type获得实体的元数据即metadata*/
    17             var entitydata = metadata.GetItems<EntityType>(DataSpace.OSpace).Single(e => objItemCollection.GetClrType(e) == entity);
    18             /*返回实体的所有键的集合*/
    19             return entitydata.KeyProperties.Select(p => p.Name).ToArray();
    20 
    21         }
    22         /// <summary>
    23         /// 获得实体对应的表名
    24         /// </summary>
    25         /// <param name="ctx"></param>
    26         /// <param name="entity"></param>
    27         /// <returns></returns>
    28         static string GetTableName(this DbContext ctx, Type entity)
    29         {
    30             var metadata = ((IObjectContextAdapter)ctx).ObjectContext.MetadataWorkspace;
    31 
    32             var storeItemCollection = metadata.GetItemCollection(DataSpace.SSpace);
    33 
    34             var entitySetBase = storeItemCollection.GetItems<EntityContainer>().Single().BaseEntitySets.Where(e => e.Name == entity.Name).Single();
    35 
    36             string tableName = entitySetBase.MetadataProperties["Schema"].Value + "." + entitySetBase.MetadataProperties["Table"].Value;
    37 
    38             return tableName;
    39         }
    40         /// <summary>
    41         /// 获得实体的所有导航属性
    42         /// </summary>
    43         /// <param name="ctx"></param>
    44         /// <param name="entity"></param>
    45         /// <returns></returns>
    46         static IEnumerable<PropertyInfo> GetNavigationPrpoperties(this DbContext ctx, Type entity)
    47         {
    48             var metadata = ((IObjectContextAdapter)ctx).ObjectContext.MetadataWorkspace;
    49 
    50             var entityType = metadata.GetItems(DataSpace.OSpace).Where(d => d.BuiltInTypeKind == BuiltInTypeKind.EntityType).OfType<EntityType>().Where(d => d.Name == entity.Name).Single();
    51 
    52             return (entityType.NavigationProperties.Select(d => entity.GetProperty(d.Name)).ToList());
    53 
    54         }
    55     }
    View Code

     7、二级缓存【参考官方Second Level Cace for EntityFramework

     1   public class EFConfiguration : DbConfiguration
     2     {
     3         public EFConfiguration()
     4         {
     5             var transactionHandler = new CacheTransactionHandler(new InMemoryCache());
     6 
     7             AddInterceptor(transactionHandler);
     8 
     9             var cachingPolicy = new CachingPolicy();
    10 
    11             Loaded +=
    12              (sender, args) => args.ReplaceService<DbProviderServices>(
    13              (s, _) => new CachingProviderServices(s, transactionHandler,
    14               cachingPolicy));
    15 
    16         }
    17 
    18     }
  • 相关阅读:
    Request源码总结
    jmeter并发顺序问题
    mysql函数应用
    读《飘》之后的感受
    itchat源码阅读一
    python将print的内容输出到txt文件
    说一下StoreBoard和纯代码编程各有什么好处吧
    CocoaPods 安装
    Silverlight调用WebSite类型的WebService,Debug时的跨域问题
    ComboBox的奇怪属性
  • 原文地址:https://www.cnblogs.com/ziranquliu/p/4772384.html
Copyright © 2020-2023  润新知