如何修改Entity Framework Db Frist模式下的Entity继承关系?

1、准备工作

Db Frist创建实体数据模型(创建edmx并不是重点,各位随意即可),此处取名ZeroCodeDB,所得文件如图所示;其中红框中的文件(ZeroCodeDB.tt)是各实体的生成的关键代码,即Entity的T4模板文件,本文正是要对此文件动刀

Demo父类代码准备如下,后续文章将会演示如何使实体User继承DemoClass、IDemoInterface<out TKey>。

using System;

namespace ZeroCode.DemoLib
{
    public class DemoClass{ }

    public interface IDemoInterface<out TKey> where TKey : IEquatable<TKey>
    {
        TKey Id { get; }
    }
}
View Code

2、分析Entity类名是如何生成的

打开ZeroCodeDB.tt文件,找到Entity的类名生成方法EntityClassOpening()如下方左图所示,对应生成的User实体类名如右图红框所示,即EntityClassOpening()方法生成了字符串 “public partial class User ”,那么只要对该方法进行操作就可以实现我们的目的了。

接下来将从情节假设中演示如何修改Entity的继承关系。

(注:T4模板代码高亮需要安装T4模板编辑器,工具-->扩展和更新-->联机-->搜索“T4 editor”)

情景一:继承某类

情景假设:不需要EF生成的继承关系,将所有实体都继承 ZeroCode.DemoLib.DemoClass

完成上述情景需要两个步骤:

  1. 在ZeroCodeDB.tt代码中添加类库ZeroCode.DemoLib的引用;
  2. 替换 _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)),保存运行T4模板。

情景二:实现某泛型接口

情景假设:需要EF生成继承关系的同时并实现IDemoInterface<out TKey>泛型接口,实体主键的类型作为泛型

完成上述情景需要四个步骤:

  1. 在ZeroCodeDB.tt代码中添加类库ZeroCode.DemoLib的引用;
  2. 在TypeMapper类添加一个获取实体主键类型的方法(见下方图2);
  3. 在CodeStringGenerator类添加一个返回实体继承关系的方法(见下方图3);
  4. 替换 _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)),保存运行T4模板。

    public string GetEntityInheritString(EntityType entity)
    {
        string baseTypeName= _typeMapper.GetTypeName(entity.BaseType);
        string idType=_typeMapper.GetIdKeyType(entity);
        string customBase=string.Format(
            CultureInfo.InvariantCulture,
            "{0}IDemoInterface<{1}>",
            string.IsNullOrEmpty(baseTypeName)?"":",",
            idType);
        return _code.StringBefore(" : ", baseTypeName + customBase);
    }

public string GetIdKeyType(EntityType type)
    {
        if(type.KeyMembers.Count>0)
        {
            EdmMember meb=((EdmMember)type.KeyMembers.FirstOrDefault());
            return meb==null?null: GetTypeName(meb.TypeUsage);
        }
        return null;
    }
情景二的关键代码
原文地址:https://www.cnblogs.com/xurongjian/p/6898948.html