Entity Framework 6 中如何获取 EntityTypeConfiguration 的 Edm 信息?(一)
1. 案例1 - 类型和表之间的EF代码优先映射
从EF6.1开始,有一种更简单的方法可以做到这一点。有关 详细信息,请参阅我的新EF6.1类型和表格之间的映射。
直接贴代码了
从EF6.1开始,有一种更简单的方法可以做到这一点。
有关 详细信息,请参阅我的新EF6.1类型和表格之间的映射。
实体框架包括MetadataWorkspace,可让您访问EF保持模型形状的元数据。问题是,映射部分 - 将实体类型映射到表和属性到列的位 - 不是公共的。
我们确实有一个工作项可以在即将发布的版本之一中公开,但在EF6和早期版本中,它仍然是内部版本。你问,为什么它是内部的...因为EF中的元数据API是一团糟。已经公开的元数据API很糟糕......但是映射更糟糕。虽然我们无法证明花时间重写整个API - 我们确实希望在公开之前将其清理一下。
然而,有一种方法可以获得信息 - 虽然非常黑客。对于Code First,您可以将编写的元数据写入EDMX格式(这是设计者使用的xml格式)。从那里,我们可以使用LINQ to XML来获取映射信息。
EF Designer怎么样?
这篇文章中的代码适用于Code First,但是它使用的是EF Designer使用的相同xml格式,因此您可以轻松地使用它来使用设计器创建的EDMX文件。
对象模型
我们将编写一个帮助程序库,以易于使用的格式返回映射信息。我们将使用以下对象模型来表示元数据。
| 
 1 
2 
3 
4 
五 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
三十 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
 | 
using System;using System.Collections.Generic;using System.Reflection;namespace MappingDemo{    /// <summary>    /// Represents the mapping of an entitiy type to one or mode tables in the database    ///    /// A single entity can be mapped to more than one table when 'Entity Splitting' is used    /// Entity Splitting involves mapping different properties from the same type to different tables    /// See http://msdn.com/data/jj591617#2.7 for more details    /// </summary>    public class TypeMapping    {        /// <summary>        /// The type of the entity from the model        /// </summary>        public Type EntityType { get; set; }        /// <summary>        /// The table(s) that the entity is mapped to        /// </summary>        public List<TableMapping> TableMappings { get; set; }    }    /// <summary>    /// Represents the mapping of an entity to a table in the database    /// </summary>    public class TableMapping    {        /// <summary>        /// The name of the table the entity is mapped to        /// </summary>        public string TableName { get; set; }        /// <summary>        /// Details of the property-to-column mapping        /// </summary>        public List<PropertyMapping> PropertyMappings { get; set; }    }    /// <summary>    /// Represents the mapping of a property to a column in the database    /// </summary>    public class PropertyMapping    {        /// <summary>        /// The property from the entity type        /// </summary>        public PropertyInfo Property { get; set; }        /// <summary>        /// The column that property is mapped to        /// </summary>        public string ColumnName { get; set; }    }} | 
填充对象模型
现在我们有了一个对象模型,我们可以编写一些hacky 不那么直观的有趣代码来填充它。
| 
 1 
2 
3 
4 
五 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
三十 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
76 
77 
78 
79 
80 
81 
82 
83 
84 
85 
86 
87 
88 
89 
90 
91 
92 
93 
94 
95 
96 
97 
98 
99 
100 
101 
102 
103 
104 
105 
106 
107 
108 
109 
110 
111 
112 
113 
114 
115 
116 
117 
118 
119 
120 
121 
122 
123 
124 
125 
126 
127 
 | 
using System;using System.Collections.Generic;using System.Data.Entity;using System.Data.Metadata.Edm;using System.Data.Entity.Infrastructure;using System.IO;using System.Linq;using System.Xml;using System.Xml.Linq;namespace MappingDemo{    /// <summary>    /// Represents that mapping between entity types and tables in an EF model    /// </summary>    public class EfMapping    {        /// <summary>        /// Mapping information for each entity type in the model        /// </summary>        public List<TypeMapping> TypeMappings { get; set; }        /// <summary>        /// Initializes an instance of the EfMapping class        /// </summary>        /// <param name="db">The context to get the mapping from</param>        public EfMapping(DbContext db)        {            this.TypeMappings = new List<TypeMapping>();            var metadata = ((IObjectContextAdapter)db).ObjectContext.MetadataWorkspace;            // Conceptual part of the model has info about the shape of our entity classes            var conceptualContainer = metadata.GetItems<EntityContainer>(DataSpace.CSpace).Single();            // Storage part of the model has info about the shape of our tables            var storeContainer = metadata.GetItems<EntityContainer>(DataSpace.SSpace).Single();            // Object part of the model that contains info about the actual CLR types            var objectItemCollection = ((ObjectItemCollection)metadata.GetItemCollection(DataSpace.OSpace));            // Mapping part of model is not public, so we need to write to xml and use 'LINQ to XML'            var edmx = GetEdmx(db);            // Loop thru each entity type in the model            foreach (var set in conceptualContainer.BaseEntitySets.OfType<EntitySet>())            {                var typeMapping = new TypeMapping                {                    TableMappings = new List<TableMapping>()                };                this.TypeMappings.Add(typeMapping);                // Get the CLR type of the entity                typeMapping.EntityType = metadata                    .GetItems<EntityType>(DataSpace.OSpace)                    .Select(e => objectItemCollection.GetClrType(e))                    .Single(e => e.FullName == set.ElementType.FullName);                // Get the mapping fragments for this type                // (types may have mutliple fragments if 'Entity Splitting' is used)                var mappingFragments = edmx                    .Descendants()                    .Single(e =>                        e.Name.LocalName == "EntityTypeMapping"                        && e.Attribute("TypeName").Value == set.ElementType.FullName)                    .Descendants()                    .Where(e => e.Name.LocalName == "MappingFragment");                foreach (var mapping in mappingFragments)                {                    var tableMapping = new TableMapping                    {                        PropertyMappings = new List<PropertyMapping>()                    };                    typeMapping.TableMappings.Add(tableMapping);                    // Find the table that this fragment maps to                    var storeset = mapping.Attribute("StoreEntitySet").Value;                    tableMapping.TableName = (string)storeContainer                        .BaseEntitySets.OfType<EntitySet>()                        .Single(s => s.Name == storeset)                        .MetadataProperties["Table"].Value;                    // Find the property-to-column mappings                    var propertyMappings = mapping                        .Descendants()                        .Where(e => e.Name.LocalName == "ScalarProperty");                    foreach (var propertyMapping in propertyMappings)                    {                        // Find the property and column being mapped                        var propertyName = propertyMapping.Attribute("Name").Value;                        var columnName = propertyMapping.Attribute("ColumnName").Value;                        tableMapping.PropertyMappings.Add(new PropertyMapping                        {                            Property = typeMapping.EntityType.GetProperty(propertyName),                            ColumnName = columnName                        });                    }                }            }        }        private static XDocument GetEdmx(DbContext db)        {            XDocument doc;            using (var memoryStream = new MemoryStream())            {                using (var xmlWriter = XmlWriter.Create(                    memoryStream, new XmlWriterSettings                    {                        Indent = true                    }))                {                    EdmxWriter.WriteEdmx(db, xmlWriter);                }                memoryStream.Position = 0;                doc = XDocument.Load(memoryStream);            }            return doc;        }    }} | 
测试出来
现在让我们通过它运行Code First模型来测试我们的代码。您会注意到我已经包含Entity Splitting来演示为什么我们需要一个实体映射到的表的List。
| 
 1 
2 
3 
4 
五 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
三十 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
76 
77 
78 
79 
80 
81 
82 
 | 
using System;using System.Collections.Generic;using System.Data.Entity;namespace MappingDemo{    class Program    {        static void Main(string[] args)        {            Database.SetInitializer(new DropCreateDatabaseAlways<BloggingContext>());            using (var db = new BloggingContext())            {                var mappingInfo = new EfMapping(db);                foreach (var item in mappingInfo.TypeMappings)                {                    Console.WriteLine(item.EntityType.FullName);                    foreach (var table in item.TableMappings)                    {                        Console.WriteLine(" => {0}", table.TableName);                        foreach (var column in table.PropertyMappings)                        {                            Console.WriteLine(                                "        {0} => {1}",                                column.Property.Name,                                column.ColumnName);                        }                    }                }            }        }    }    public class BloggingContext : DbContext    {        public DbSet<Blog> Blogs { get; set; }        public DbSet<Post> Posts { get; set; }        protected override void OnModelCreating(DbModelBuilder modelBuilder)        {            // Rename a column so that not all property/column names match            modelBuilder.Entity<Post>()                .Property(p => p.PostId)                .HasColumnName("post_id");            // Perform 'Entity Splitting' on the Blog entity to test            // mapping a single entity to multiple tables            modelBuilder.Entity<Blog>()                .Map(m =>                    {                        m.Properties(b => new { b.Name, b.Url });                        m.ToTable("Blog_Details");                    })                .Map(m =>                {                    m.Properties(b => new { b.Image });                    m.ToTable("Blog_Photo");                });        }    }    public class Blog    {        public int BlogId { get; set; }        public string Name { get; set; }        public string Url { get; set; }        public byte[] Image { get; set; }        public virtual List<Post> Posts { get; set; }    }    public class Post    {        public int PostId { get; set; }        public string Title { get; set; }        public string Content { get; set; }        public int BlogId { get; set; }        public virtual Blog Blog { get; set; }    }} | 
运行我们的应用程序会产生以下输出。
![]()
有关
2. 案例2(已经在 EF6.0.0 中测试)
增加 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.Core.Objects;
using System.Data.Entity.Infrastructure;
using System.Linq; namespace Sino.SnapshotComparsion.Data
{
/// <summary>
/// Entity Framework 6 中的 DbContext 扩展
/// </summary>
public static class DbContextExtensions
{
private readonly static Dictionary<string, EntitySetBase> _mappingCache = new Dictionary<string, EntitySetBase>(); private static EntitySetBase GetEntitySet(DbContext dbContext, Type type)
{
if (dbContext == null)
{
throw new ArgumentNullException("dbContext");
}
if (type == null)
{
throw new ArgumentNullException("type");
}
if (_mappingCache.ContainsKey(type.FullName))
{
return _mappingCache[type.FullName];
}
string baseTypeName = type.BaseType.Name;
string typeName = type.Name; ObjectContext octx = ((IObjectContextAdapter)dbContext).ObjectContext;
EntitySetBase es = octx.MetadataWorkspace
.GetItemCollection(DataSpace.SSpace)
.GetItems<EntityContainer>()
.SelectMany(c => c.BaseEntitySets
.Where(e => e.Name == typeName
|| e.Name == baseTypeName))
.FirstOrDefault();
if (es == null)
{
throw new ArgumentException("Entity type not found in GetEntitySet", typeName);
}
_mappingCache.Add(type.FullName, es);
return es;
} public static string GetTableName(DbContext context, Type type)
{
var metadata = ((IObjectContextAdapter)context).ObjectContext.MetadataWorkspace; // Get the part of the model that contains info about the actual CLR types
var objectItemCollection = ((ObjectItemCollection)metadata.GetItemCollection(DataSpace.OSpace)); // Get the entity type from the model that maps to the CLR type
var entityType = metadata
.GetItems<EntityType>(DataSpace.OSpace)
.Single(e => objectItemCollection.GetClrType(e) == type); // Get the entity set that uses this entity type
var 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
var mapping = metadata.GetItems<EntityContainerMapping>(DataSpace.CSSpace)
.Single()
.EntitySetMappings
.Single(s => s.EntitySet == entitySet); // Find the storage entity set (table) that the entity is mapped
var table = mapping
.EntityTypeMappings.Single()
.Fragments.Single()
.StoreEntitySet; // Return the table name from the storage entity set
return (string)table.MetadataProperties["Table"].Value ?? table.Name;
} /// <summary>
/// 获取映射的表的名称
/// </summary>
/// <typeparam name="TEntity">EF 实体的类型</typeparam>
/// <param name="dbContext">EF的 DbContext 上下文</param>
/// <returns></returns>
public static string[] GetPrimaryKeyName<TEntity>(this DbContext dbContext)
{
return GetPrimaryKeyName(dbContext, typeof(TEntity));
} /// <summary>
/// 获取映射的表的主键名称集合
/// </summary>
/// <param name="dbContext">EF的 DbContext 上下文</param>
/// <param name="type">EF 实体的类型</param>
/// <returns></returns>
public static string[] GetPrimaryKeyName(this DbContext dbContext, Type type)
{
EntitySetBase es = GetEntitySet(dbContext, type);
return es.ElementType.KeyProperties.Select(c => c.Name).ToArray();
} /// <summary>
/// 获取映射的表的主键名称集合的字符串形式
/// </summary>
/// <param name="dbContext">EF的 DbContext 上下文</param>
/// <param name="type">EF 实体的类型</param>
/// <returns></returns>
public static string GetPrimaryKeyNameString(this DbContext dbContext, Type type)
{
return string.Join(",", GetPrimaryKeyName(dbContext, type));
} /// <summary>
/// 获取映射的表的主键名称集合的字符串形式
/// </summary>
/// <typeparam name="TEntity">EF 实体的类型</typeparam>
/// <param name="dbContext">EF的 DbContext 上下文</param>
/// <returns></returns>
public static string GetPrimaryKeyNameString<TEntity>(this DbContext dbContext)
{
return GetPrimaryKeyNameString(dbContext, typeof(TEntity));
}
}
}
3. 案例3 - EF6.1类型和表之间的映射
前段时间我在博客上写了一篇关于如何找到给定实体映射到的表的文章。该帖子中的解决方案解决了访问此信息的API是内部的问题。在EF6.1中,我们将映射API公之于众,因此它现在变得更加容易。
此代码的另一个优点是它适用于Code First和EF Designer模型。
代码
不用多说,这里是找到给定CLR类型的表名的代码。我已经包含了一个完整的控制台应用程序列表,该应用程序演示了代码的运行情况,但是如果您需要的话,您可以获取GetTableName方法。
| 
 1 
2 
3 
4 
五 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
三十 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
76 
77 
78 
79 
80 
81 
82 
83 
84 
85 
86 
87 
 | 
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.Linq;namespace MappingDemo{    class Program    {        static void Main(string[] args)        {            using (var db = new BloggingContext())            {                Console.WriteLine("Blog maps to: {0}", GetTableName(typeof(Blog), db));                Console.WriteLine("Post maps to: {0}",  GetTableName(typeof(Post), db));            }        }        public static string GetTableName(Type type, DbContext context)        {            var metadata = ((IObjectContextAdapter)context).ObjectContext.MetadataWorkspace;            // Get the part of the model that contains info about the actual CLR types            var objectItemCollection = ((ObjectItemCollection)metadata.GetItemCollection(DataSpace.OSpace));            // Get the entity type from the model that maps to the CLR type            var entityType = metadata                    .GetItems<EntityType>(DataSpace.OSpace)                    .Single(e => objectItemCollection.GetClrType(e) == type);            // Get the entity set that uses this entity type            var 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            var mapping = metadata.GetItems<EntityContainerMapping>(DataSpace.CSSpace)                    .Single()                    .EntitySetMappings                    .Single(s => s.EntitySet == entitySet);            // Find the storage entity set (table) that the entity is mapped            var table = mapping                .EntityTypeMappings.Single()                .Fragments.Single()                .StoreEntitySet;            // Return the table name from the storage entity set            return (string)table.MetadataProperties["Table"].Value ?? table.Name;        }    }    public class BloggingContext : DbContext    {        public DbSet<Blog> Blogs { get; set; }        public DbSet<Post> Posts { get; set; }        protected override void OnModelCreating(DbModelBuilder modelBuilder)        {            modelBuilder.Entity<Blog>().ToTable("t_blog");            modelBuilder.Entity<Post>().ToTable("t_post");        }    }    public class Blog    {        public int BlogId { get; set; }        public string Url { get; set; }        public List<Post> Posts { get; set; }    }    public class Post    {        public int PostId { get; set; }        public string Title { get; set; }        public string Body { get; set; }        public int BlogId { get; set; }        public Blog Blog { get; set; }    }} | 
高级映射的调整
EF支持称为“实体拆分”的高级映射模式。在此模式中,您可以在多个表之间拆分实体的属性。以下是实体拆分Post类的Fluent API调用示例。
| 
 1 
2 
3 
4 
五 
6 
7 
8 
9 
10 
11 
 | 
modelBuilder.Entity<Post>()    .Map(m =>    {        m.Properties(p => new { p.PostId, p.Title, p.BlogId });        m.ToTable("t_post");    })    .Map(m =>    {        m.Properties(p => new { p.PostId, p.Body });        m.ToTable("t_post_body");    }); | 
为了处理这个问题,我们可以更新GetTableName方法以返回类型映射到的表的可枚举数。对前一个实现的唯一更改是从映射片段中查找表名的最后两个代码块。
| 
 1 
2 
3 
4 
五 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
三十 
31 
32 
33 
 | 
public static IEnumerable<string> GetTableName(Type type, DbContext context){    var metadata = ((IObjectContextAdapter)context).ObjectContext.MetadataWorkspace;    // Get the part of the model that contains info about the actual CLR types    var objectItemCollection = ((ObjectItemCollection)metadata.GetItemCollection(DataSpace.OSpace));    // Get the entity type from the model that maps to the CLR type    var entityType = metadata            .GetItems<EntityType>(DataSpace.OSpace)            .Single(e => objectItemCollection.GetClrType(e) == type);    // Get the entity set that uses this entity type    var 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    var mapping = metadata.GetItems<EntityContainerMapping>(DataSpace.CSSpace)            .Single()            .EntitySetMappings            .Single(s => s.EntitySet == entitySet);    // Find the storage entity sets (tables) that the entity is mapped    var tables = mapping        .EntityTypeMappings.Single()        .Fragments;    // Return the table name from the storage entity set    return tables.Select(f => (string)f.StoreEntitySet.MetadataProperties["Table"].Value ?? f.StoreEntitySet.Name);} | 
其他变化
有些人已从这篇文章中获取代码并将其扩展以适应其他映射场景:
- 属性和列之间的映射 - 本杰明马蒂
 - 在模型中使用继承进行映射 --Brian Lowry
 
有关
谢谢浏览!
Entity Framework 6 中如何获取 EntityTypeConfiguration 的 Edm 信息?(一)的更多相关文章
- 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 信息?(三)
		
接着上一篇,我们继续来优化. 直接贴代码了: LambdaHelper.cs using System; using System.Collections.Generic; using System. ...
 - Entity Framework 6 中如何获取 EntityTypeConfiguration 的 Edm 信息?(二)
		
接着上一篇 直接贴代码了: using System; using System.Collections.Generic; using System.Data.Entity; using System ...
 - 浅析Entity Framework Core中的并发处理
		
前言 Entity Framework Core 2.0更新也已经有一段时间了,园子里也有不少的文章.. 本文主要是浅析一下Entity Framework Core的并发处理方式. 1.常见的并发处 ...
 - 在Entity Framework 7中进行数据迁移
		
(此文章同时发表在本人微信公众号“dotNET每日精华文章”,欢迎右边二维码来关注.) 题记:虽然EF7重新设计了Entity Framework,不过也还是能够支持数据迁移的. Entity Fra ...
 - [Programming Entity Framework] 第3章 查询实体数据模型(EDM)(一)
		
http://www.cnblogs.com/sansi/archive/2012/10/18/2729337.html Programming Entity Framework 第二版翻译索引 你可 ...
 - 如何处理Entity Framework / Entity Framework Core中的DbUpdateConcurrencyException异常(转载)
		
1. Concurrency的作用 场景有个修改用户的页面功能,我们有一条数据User, ID是1的这个User的年龄是20, 性别是female(数据库中的原始数据)正确的该User的年龄是25, ...
 - Entity Framework添加记录时获取自增ID值
		
与Entity Framework相伴的日子痛并快乐着.今天和大家分享一下一个快乐,两个痛苦. 先说快乐的吧.Entity Framework在将数据插入数据库时,如果主键字段是自增标识列,会将该自增 ...
 
随机推荐
- Core源码(四)IEnumerable
			
首先我们去core的源码中去找IEnumerable发现并没有,如下 Core中应该是直接使用.net中对IEnumerable的定义 自己实现迭代器 迭代器是通过IEnumerable和IEnume ...
 - vue-父组件和路由
			
父子组件之间传值 <div id="app"> <com1 v-bind:parentmsg="msg" @func="getMsg ...
 - C++ 运算符重载的基本概念
			
01 运算符重载的需求 C++ 预定义的运算符,只能用于基本数据类型的运算:整型.实型.字符型.逻辑型等等,且不能用于对象的运算.但是我们有时候又很需要在对象之间能用运算符,那么这时我们就要重载运算符 ...
 - Docker基础概念与安装
			
Docker是什么? Docker最初是dotCloud公司的创始人Solomon Hyks在法国期间发起的一个公司内部项目,它是基于dotCloud公司多年云服务技术的一次革新,并于2013年3月以 ...
 - 从《华为的冬天》到AI的冬天 | 甲子光年
			
知难不难,惶者生存. 作者 | DougLong 编辑 | 火柴Q.甲小姐 *本文为甲子光年专栏作家DougLong独家稿件.作者为AI从业者.Gary Marcus<Rebooting AI& ...
 - 个人博客如何开启 https
			
以前写过利用 wordpress 搭建的一个博客『个人博客搭建( wordpress )』,绑定了域名,但是没开启 https,在浏览博客的时候浏览器会提示不安全.下面来谈下个人博客如何免费申请证书, ...
 - git设置github的远程仓库的相关操作
			
git能够把github作为远程仓库,本地可以进行推送有关变更,从而多人可以进行协作开发工作. 1 ssh-keygen -t rsa -C "your-email@163. ...
 - CODING 告诉你硅谷项目经理的项目管理之道
			
写在前面 优秀的项目管理者是怎么工作的,如何把一个研发团队的绩效激发到最大? 我们精心挑选了几篇硅谷科技公司研发管理者的 README 进行翻译. README 主要用来向团队成员展示项目管理者的工作 ...
 - [视频教程] 使用docker的方式安装redis
			
直接使用docker拉取redis的镜像,并且进行端口映射与文件目录共享,这样可以直接在宿主机的端口上就可以进行访问了.其实本质上也是在一个简化版的ubuntu的容器内安装好的redis-server ...
 - 基于tiny4412的Linux内核移植 --- aliases节点解析【转】
			
转自:https://www.cnblogs.com/pengdonglin137/p/5252348.html 阅读目录(Content) 作者信息 平台简介 正文 回到顶部(go to top) ...