EntityFramework 6 如何通过反射获得身份字段?

EntityFramework 6 How to get identity-field with reflection?(EntityFramework 6 如何通过反射获得身份字段?)
本文介绍了EntityFramework 6 如何通过反射获得身份字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有类型参数 T 的泛型方法,其中 T 是 EF 模型中的实体类型.我需要获取此类型中标识字段的名称.我看到了这篇文章:有没有办法通过反射或其他方式获取实体 id-field 的名称?但是我不明白 Tevin 在谈到 EntitySetBaseEntityTypeBase 类型时在说什么.如果 EntityTypeBase 是模型中实体之一的类型,则 EF6 没有属性 KeyMembers.

I have a generic method with type parameter T, where T is the type of entity in EF model. I need to get the name of identifying field in this type. I saw this article: Is there a way to get entity id-field's name by reflection or whatever? But I can't understand, what Tevin talking about when he talks about EntitySetBase and EntityTypeBase types. If EntityTypeBase is type of one of the entities in model, so then EF6 have no property KeyMembers.

推荐答案

我觉得只靠反射是不可能得到主键的.

I don't think it's possible to get the primary keys only by reflection.

首先,让我们看看 EF 如何确定哪些属性将成为主键,而不管顺序/优先级如何

First, let's find out how EF determine which property(ies) that will be primary key(s) regardless of the order / priority

  • 由 公约

主键的实体框架约定是:

The Entity Framework convention for primary keys is:

  1. 您的类定义了一个名为ID"或Id"的属性
  2. 或类名后跟ID"或Id"

我们可以使用GetProperties来比较属性名.

We can use GetProperties and compare the property name.

var key = type.GetProperties().FirstOrDefault(p => 
    p.Name.Equals("ID", StringComparison.OrdinalIgnoreCase) 
    || p.Name.Equals(type.Name + "ID", StringComparison.OrdinalIgnoreCase));

  • [KeyAttribute]
  • 我们可以使用CustomAttributes并比较属性类型.

    We can use CustomAttributes and compare the attribute type.

    var key = type.GetProperties().FirstOrDefault(p => 
        p.CustomAttributes.Any(attr => attr.AttributeType == typeof(KeyAttribute)));
    

    • 由 Fluent Api
    • 这是一个很难做到的, modelBuilder 被封装在 OnModelCreating 中,即使我们将 modelBuilder 保存为 field/属性,从HasKey函数中提取key还是很困难的,一切都被封装了.您可以查看源代码.EF 中的所有内容都取决于 ObjectContext 并且一旦 ObjectContext 被调用,例如这行代码,

      This is the one that's difficult to do, modelBuilder is encapsulated in the OnModelCreating and even if we save the modelBuilder somewhere as field/property, it's still difficult to extract the key from HasKey function, everything is encapsulated. You can check the source code. And everything in EF depends on ObjectContext and once the ObjectContext is called, for example this line of code,

      ((IObjectContextAdapter)context).ObjectContext
      

      然后将建立与数据库的连接,您可以使用分析器进行检查.这是源代码的代码摘录.

      then a connection to the database will be made, you can check using profiler. And here is the code excerpt of the source code.

      public override ObjectContext ObjectContext
      {
          get
          {
              Initialize();
              return ObjectContextInUse;
          }
      }
      
      public void Initialize()
      {
          InitializeContext();
          InitializeDatabase();
      }
      

      因此,目前获取主键的唯一可能方法是通过对象集、实体集、键成员等,如 这篇文章

      Therefore, currently the only possible way to get the primary key(s) is through object set, entity set, key members, etc as explained in this post

      var keyNames = set.EntitySet.ElementType.KeyMembers.Select(k => k.Name);
      

      这篇关于EntityFramework 6 如何通过反射获得身份字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)