Entity Framework 6 中如何获取 EntityTypeConfiguration 的 Edm 信息?(三)
接着上一篇,我们继续来优化。
直接贴代码了:
LambdaHelper.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks; namespace EntityFrameworkSample
{
public static class LambdaHelper
{
public static string GetPropName<TEntityType, TProperty>(Expression<Func<TEntityType, TProperty>> propertyExpression)
{
MemberExpression memberExpression;
if (!InspectIsMemberExpression<TEntityType, TProperty>(propertyExpression, true, out memberExpression))
{
return null;
}
return memberExpression.Member.Name;
} public static bool InspectIsMemberExpression<TEntityType, TProperty>(Expression<Func<TEntityType, TProperty>> propertyExpression)
{
return InspectIsMemberExpression<TEntityType, TProperty>(propertyExpression, true);
} public static bool InspectIsMemberExpression<TEntityType, TProperty>(Expression<Func<TEntityType, TProperty>> propertyExpression, bool throwExOnNull)
{
MemberExpression memberExpression;
return InspectIsMemberExpression<TEntityType, TProperty>(propertyExpression, throwExOnNull, out memberExpression);
} public static bool InspectIsMemberExpression<TEntityType, TProperty>(Expression<Func<TEntityType, TProperty>> propertyExpression, bool throwExOnNull, out MemberExpression memberExpression)
{
if (propertyExpression == null)
{
throw new ArgumentNullException("express");
}
memberExpression = propertyExpression.Body as MemberExpression;
if (memberExpression == null)
{
if (throwExOnNull)
{
throw new ArgumentException("请为类型 \"" + typeof(TEntityType).FullName + "\" 的指定一个字段(Field)或属性(Property)作为 Lambda 的主体(Body)。");
}
return false;
}
return true;
}
}
}
DbContextExtensions.cs
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Core.Mapping;
using System.Data.Entity.Core.Metadata.Edm;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.ModelConfiguration;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Linq;
using EntityFramework.Extensions;
using System.Linq.Expressions; namespace EntityFrameworkSample
{
public enum AcquiredEdmType
{
TableName, FirstPrimaryKeyNameString, ColumnName
} public static class DbContextExtensions
{
#region 基础方法 public static string GetTableName<TEntity>(this DbContext context)
{
return GetTableName(context, typeof(TEntity));
} public static string GetTableName(this DbContext context, Type type)
{
return GetTableNameOrColumnName(context, type, AcquiredEdmType.TableName);
} public static string GetFirstPrimaryKeyName<TEntity>(this DbContext context)
{
return GetFirstPrimaryKeyName(context, typeof(TEntity));
} public static string GetFirstPrimaryKeyName(this DbContext context, Type type)
{
return GetTableNameOrColumnName(context, type, AcquiredEdmType.FirstPrimaryKeyNameString);
} public static string GetColumnName<TEntity, TProperty>(this DbContext context, Expression<Func<TEntity, TProperty>> propertyExpression)
{
return GetTableNameOrColumnName(context, typeof(TEntity), AcquiredEdmType.ColumnName, LambdaHelper.GetPropName(propertyExpression));
} public static string GetColumnName(this DbContext context, Type type, string propertyName)
{
return GetTableNameOrColumnName(context, type, AcquiredEdmType.ColumnName, propertyName);
} private static string GetTableNameOrColumnName(this DbContext context, Type type, AcquiredEdmType edmType, string propertyName = null)
{
var metadata = ((IObjectContextAdapter)context).ObjectContext.MetadataWorkspace; // Get the part of the model that contains info about the actual CLR types
ObjectItemCollection objectItemCollection = ((ObjectItemCollection)metadata.GetItemCollection(DataSpace.OSpace)); // Get the entity type from the model that maps to the CLR type
EntityType entityType = metadata
.GetItems<EntityType>(DataSpace.OSpace)
.Single(e => objectItemCollection.GetClrType(e) == type); // Get the entity set that uses this entity type
EntitySet entitySet = metadata
.GetItems<EntityContainer>(DataSpace.CSpace)
.Single()
.EntitySets
.Single(s => s.ElementType.Name == entityType.Name); // Find the mapping between conceptual and storage model for this entity set
EntitySetMapping mapping = metadata.GetItems<EntityContainerMapping>(DataSpace.CSSpace)
.Single()
.EntitySetMappings
.Single(s => s.EntitySet == entitySet); // Find the storage entity set (table) that the entity is mapped
EntitySet tableEntitySet = mapping
.EntityTypeMappings.Single()
.Fragments.Single()
.StoreEntitySet; // Return the table name from the storage entity set
object objTableName = tableEntitySet.MetadataProperties["Table"].Value;
string tableName = objTableName == null ? tableEntitySet.Name : Convert.ToString(objTableName); switch (edmType)
{
case AcquiredEdmType.TableName:
return tableName;
case AcquiredEdmType.FirstPrimaryKeyNameString:
{
var firstKeyProp = tableEntitySet.ElementType.KeyProperties[];
//return tableName + "." + firstKeyProp.Name;
return firstKeyProp.Name;
}
case AcquiredEdmType.ColumnName:
{
// Find the storage property (column) that the property is mapped
var columnName = mapping
.EntityTypeMappings.Single()
.Fragments.Single()
.PropertyMappings
.OfType<ScalarPropertyMapping>()
.Single(m => m.Property.Name == propertyName)
.Column
.Name; //return tableName + "." + columnName;
return columnName;
}
default:
throw new ArgumentNullException("Invalid argument");
}
} #endregion #region 额外方法 #endregion
}
}
Program.cs
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Core.Mapping;
using System.Data.Entity.Core.Metadata.Edm;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.ModelConfiguration;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Linq;
using EntityFramework.Extensions;
using System.Linq.Expressions;
using EntityFrameworkSample; namespace EntityFrameworkSample
{
class Program
{
static void Main(string[] args)
{
using (var context = new BloggingContext(@"Data Source=.\SQLExpress;Initial Catalog=TestDB;Persist Security Info=True;User ID=sa;Password=123456"))
{
string blogTableName = context.GetTableName<Blog>();
string postTableName = context.GetTableName<Post>(); Console.WriteLine("Blog maps to: {0}", blogTableName);
Console.WriteLine("Post maps to: {0}", postTableName); string blogPrimaryKeyName = context.GetFirstPrimaryKeyName<Blog>();
string postPrimaryKeyName = context.GetFirstPrimaryKeyName<Post>(); Console.WriteLine("Blog primary key name: {0}", blogPrimaryKeyName);
Console.WriteLine("Post primary key name: {0}", postPrimaryKeyName); //System.Diagnostics.Stopwatch watch = System.Diagnostics.Stopwatch.StartNew();
//for (int i = 0; i < 600000; i++)
//{
// context.GetColumnName<Blog, string>(c => c.BlogUrl); //经过测试,循环60万次,耗时14秒
//}
//watch.Stop();
//Console.WriteLine("耗时:{0}秒", (watch.ElapsedMilliseconds / 1000).ToString()); string blogUrlColumnName = context.GetColumnName<Blog, string>(c => c.BlogUrl);
string postTitleColumnName = context.GetColumnName<Post, string>(c => c.PostTitle); //Console.WriteLine("Blog.BlogUrl maps to: {0}.{1}", blogTableName, blogUrlColumnName);
Console.WriteLine("Post.PostTitle maps to: {0}.{1}", postTableName, postTitleColumnName); }
Console.ReadLine();
} } public class BloggingContext : DbContext
{
public BloggingContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{ } public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new BlogMap());
modelBuilder.Configurations.Add(new PostMap());
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
base.OnModelCreating(modelBuilder);
}
} public class Blog
{
public int Id { get; set; }
public string BlogUrl { get; set; } public List<Post> Posts { get; set; }
} public class Post
{
public int Id { get; set; }
public string PostTitle { get; set; }
public string Body { get; set; } public int BlogId { get; set; }
public Blog Blog { get; set; }
} public class BlogMap : EntityTypeConfiguration<Blog>
{
public BlogMap()
{
this.HasKey(c => c.Id);
this.ToTable("t_blog");
this.Property(c => c.Id).HasColumnName("BlogId");
this.Property(c => c.BlogUrl).HasColumnName("Url");
}
} public class PostMap : EntityTypeConfiguration<Post>
{
public PostMap()
{
this.HasKey(c => c.Id);
this.ToTable("t_post");
this.Property(c => c.Id).HasColumnName("PostId");
this.Property(c => c.PostTitle).HasColumnName("Title");
}
}
}
运行截图:
谢谢浏览!
Entity Framework 6 中如何获取 EntityTypeConfiguration 的 Edm 信息?(三)的更多相关文章
- Entity Framework 6 中如何获取 EntityTypeConfiguration 的 Edm 信息?(一)
1. 案例1 - 类型和表之间的EF代码优先映射 从EF6.1开始,有一种更简单的方法可以做到这一点.有关 详细信息,请参阅我的新EF6.1类型和表格之间的映射. 直接贴代码了 从EF6.1开始,有一 ...
- Entity Framework 6 中如何获取 EntityTypeConfiguration 的 Edm 信息?(五)
直接贴代码了: NewsInfo 实体类: public class NewsInfo { public int NewsInfoId { get; set; } public string News ...
- Entity Framework 6 中如何获取 EntityTypeConfiguration 的 Edm 信息?(四)
经过上一篇,里面有测试代码,循环60万次,耗时14秒.本次我们增加缓存来优化它. DbContextExtensions.cs using System; using System.Collectio ...
- Entity Framework 6 中如何获取 EntityTypeConfiguration 的 Edm 信息?(二)
接着上一篇 直接贴代码了: using System; using System.Collections.Generic; using System.Data.Entity; using System ...
- [Programming Entity Framework] 第3章 查询实体数据模型(EDM)(一)
http://www.cnblogs.com/sansi/archive/2012/10/18/2729337.html Programming Entity Framework 第二版翻译索引 你可 ...
- 浅析Entity Framework Core中的并发处理
前言 Entity Framework Core 2.0更新也已经有一段时间了,园子里也有不少的文章.. 本文主要是浅析一下Entity Framework Core的并发处理方式. 1.常见的并发处 ...
- 在Entity Framework 7中进行数据迁移
(此文章同时发表在本人微信公众号“dotNET每日精华文章”,欢迎右边二维码来关注.) 题记:虽然EF7重新设计了Entity Framework,不过也还是能够支持数据迁移的. Entity Fra ...
- 《Entity Framework 6 Recipes》中文翻译系列 (17) -----第三章 查询之分页、过滤和使用DateTime中的日期部分分组
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 3-12 分页和过滤 问题 你想使用分页和过滤来创建查询. 解决方案 假设你有如图3 ...
- 如何处理Entity Framework / Entity Framework Core中的DbUpdateConcurrencyException异常(转载)
1. Concurrency的作用 场景有个修改用户的页面功能,我们有一条数据User, ID是1的这个User的年龄是20, 性别是female(数据库中的原始数据)正确的该User的年龄是25, ...
随机推荐
- 【agc028E】High Elements(动态规划,线段树,贪心)
[agc028E]High Elements(动态规划,线段树,贪心) 题面 AtCoder 你有一个\([1,N]\)的排列\(P\). 一个长度为\(N\)的字符串\(S\)是好的,当且仅当: 两 ...
- 使用Java操作Elasticsearch(Elasticsearch的java api使用)
1.Elasticsearch是基于Lucene开发的一个分布式全文检索框架,向Elasticsearch中存储和从Elasticsearch中查询,格式是json. 索引index,相当于数据库中的 ...
- CentOS安装Docker-ce并配置中国国内加速(aliyun)镜像
前提条件 1.系统.内核 CentOS7 要求64位系统.内核版本3.10以上 CentOS6 要求版本在6.5以上,系统64位.内核版本2.6.32-431以上 查看内核版本号 uname -r # ...
- 全栈工程师对Python面试中is和==区别的详细解说!看完真的学到了!
面试实习生的时候,当问到 is 和 == 的区别时,很多同学都答不上来,搞不清两者什么时候返回一致,什么时候返回不一致.本文我们来看一下这两者的区别. 我们先来看几个例子: a = "hel ...
- ASP.Net MVC 路由及路由调试工具RouteDebug
一.路由规则 1.可以创建多条路由规则,每条路由的name属性不相同 2.路由规则有优先级,最上面的路由规则优先级越高 App_Start文件下的:RouteConfig.cs public stat ...
- 「SAP技术」SAP 如何看序列号被包在哪些HU里?
「SAP技术」SAP 如何看序列号被包在哪些HU里? 事务代码SE16 ,表名OBJK, 输入物料号,序列号,HeadTable 输入值SER06, 查询结果如下, 根据objlist, 去表ser0 ...
- 使用weui开发微信小程序
一.使用weui 学习一个新的技术,想要最短时间掌握并熟练使用它,那就是直接做项目了.把技术直接应用到项目中来,直接做出东西,这是我的方法,因为我很懒不太喜欢看一步一步看文档,看理论. 那怎么使用we ...
- 13. 抽象类 & 接口
一.抽象类 // 抽象类Shape public abstract class Shape { // 1. 成员变量 private String color; // 2. 初始化块 { System ...
- Java jdom解析xml文件带冒号的属性
Java jdom解析xml文件带冒号的属性 转载请标明出处: https://dujinyang.blog.csdn.net/article/details/99644824 本文出自:[奥特曼超人 ...
- 3.Python网络编程_多任务问题抛出
#单线程程序 import time def sing(): """唱歌5秒钟""" for i in range(5): print(&q ...