【问题标题】:How to avoid hardcoded field names in entity framework?如何避免实体框架中的硬编码字段名称?
【发布时间】:2009-03-25 23:38:30
【问题描述】:

如何避免在实体框架中使用硬编码的表名和字段名?例如:

  Contact contact =
        contactQuery.Include("SalesOrderHeader.SalesOrderDetail")
        .FirstOrDefault();

有没有办法从上下文或元数据中获取该信息?我希望能够说 SalesOrderHeader.TableName 或 SalesOrderHeaderFields.SalesOrderDetails.FieldName

【问题讨论】:

    标签: c# .net entity-framework


    【解决方案1】:

    如果您想使用实体框架元数据,您需要查看挂在ObjectContext 之外的MetadataWorkspace

    起点是获取您的基本类型的 EntityType,在您的情况下为 Contact。

    我有一个EF tips series,在Tip 13 中,我在MetadataWorkspace 上显示了一个扩展方法,该方法获取特定CLR 类型的EntityType

    public static EntityType GetCSpaceEntityType<T>(
            this MetadataWorkspace workspace);
    

    你可以这样使用:

    var contactEntity = ctx.MetadataWorkspace.GetCSpaceEntityType<Contact>();
    

    一旦你有了这个,你可以查看它的 NavigationProperties 来找到关系和你感兴趣的名字,包括:

    foreach(var np in contactEntity.NavigationProperties)
    {
        Console.WriteLine("Include: {0}", np.Name);
        Console.WriteLine("... Recursively include ");
        EntityType relatedType = 
           (np.ToEndMember.TypeUsage.EdmType as RefType).ElementType;
        //TODO: go repeat the same process... i.e. look at the relatedTypes 
        // navProps too until you decide to stop.
    }
    

    当然,您如何决定要包含的内容取决于您自己。 希望这会有所帮助

    亚历克斯

    【讨论】:

      【解决方案2】:

      阅读Say goodbye to the hardcoded ObjectQuery(T).Include calls,您将能够使用 lambda 和 linq 表达式树进行如下操作:

      Dim c = GetObjectContext()
      Dim query = c.Vendors.Include(Function(v) v.Contact.Addresses.Single.State)
      

      还有一个 C# 示例。

      HTH

      【讨论】:

        【解决方案3】:

        只是一个属性名,可以通过反射获取。

        【讨论】:

        • 我猜,但是通过反射非常昂贵。
        • 并非如此。它永远不会改变,所以你只需要做一次。使其成为类静态属性。它将在几微秒内初始化,您再也不需要这样做了。
        • 我有一个使用表达式树的更好的非常动态的解决方案,请参阅我的回答:stackoverflow.com/questions/683960/…
        【解决方案4】:

        示例(希望听到更好的想法,没有找到像 VB GetType 那样接受类型名称作为参考的方法):

        VB:

        <Extension()>
        Function GetRelation(Of TEntity As Type)(entity As TEntity,
         ParamArray path() As TEntity) As String
          GetRelation = entity.Name
          For Each type In path
            GetRelation &= "." & type.Name
          Next
        End Function
        
        'Here is your line:
        Dim x = Context.Employee.Include(
         GetType(Contact).GetRelation(GetType(SalesOrderHeader),
         GetType(SalesOrderDetail)))
        

        C#:

        static string GetRelation<TEntity>(this TEntity entity, params TEntity[] path)
         where TEntity : Type
        {
           string ret = entity.Name;
           foreach (TEntity type in path) ret += "." + type.Name;
           return ret;
        }
        
        //Put your line here:
        var x = context.Employee.Include(typeof(Contact).GetRelation(
         typeof(SalesOrderHeader),
         typeof salesOrderDetail)));
        

        我希望有一种动态的反思方式…… 再次,我思想开放,任何建议都会受到祝福 谢谢

        【讨论】:

        • 该代码不起作用。您需要指定实体集名称和属性名称,而不是类型名称。给出的代码将在对 Include 的调用中生成不正确的参数
        • ...除非属性名称和实体集名称恰好与类型名称相同。
        猜你喜欢
        • 1970-01-01
        • 2018-10-29
        • 1970-01-01
        • 2018-11-19
        • 2019-03-18
        • 1970-01-01
        • 2018-02-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多