我怎样才能提取数据库表和列名上EF4实体的属性? [英] How can I extract the database table and column name for a property on an EF4 entity?

查看:104
本文介绍了我怎样才能提取数据库表和列名上EF4实体的属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一个使用EF4数据访问层的应用程序审计组件。我能够非常容易地确定哪些实体已被修改,并通过ObjectStateEntry对象我可以提取被修改的原始值,电流值,实体名称和属性名称,但我也想提取原始表在SQL Server中使用的列名(因为他们并不总是符合模型的实体和属性名)

I'm writing an auditing component for an application that uses EF4 for the data access layer. I'm able to very easily determine which entities have been modified, and via the ObjectStateEntry object I can extract the original values, current values, entity name, and property names that were modified, but I would also like to extract the raw table and and column names used in SQL Server (since they do not always match the entity and property names of the model)

有谁知道一个好办法做到这一点?它甚至有可能?映射显然是存储在MSL,但我不能想出一个办法以编程方式访问这些映射。

Does anyone know of a good way to do this? Is it even possible? The mappings are obviously stored in the MSL, but I can't figure out a way to programmatically access those mappings.

推荐答案

在一窥我看到了一个实体框架模型设计,它使用了 EdmEntityTypeAttribute DataMemberAttribute 来装点生成的类和属性。他们每个人都有一个名称包含映射实体的名称(表,列分别)属性。当属性名称的列的名称相匹配,设计师没有为位置参数名称提供一个值。
下面的代码为我工作得很好。

After a peek into a entity framework model designer I saw that it uses the EdmEntityTypeAttribute and DataMemberAttribute to decorate generated classes and properties. Each of them have a Name property which contains the name of the mapped entity (table, column respectively). When the property name matches the name of the column, the designer does not supply a value for positional argument Name. The code below works fine for me.

 private static string GetTableName<T>() where T : EntityObject
    {
        Type type = typeof(T);
        var at = GetAttribute<EdmEntityTypeAttribute>(type);
        return at.Name;
    }

    private static string GetColumnName<T>(Expression<Func<T, object>> propertySelector) where T : EntityObject
    {
        Contract.Requires(propertySelector != null, "propertySelector is null.");

        PropertyInfo propertyInfo = GetPropertyInfo(propertySelector.Body);
        DataMemberAttribute attribute = GetAttribute<DataMemberAttribute>(propertyInfo);
        if (String.IsNullOrEmpty(attribute.Name))
        {
            return propertyInfo.Name;
        }
        return attribute.Name;
    }

    private static T GetAttribute<T>(MemberInfo memberInfo) where T : class
    {
        Contract.Requires(memberInfo != null, "memberInfo is null.");
        Contract.Ensures(Contract.Result<T>() != null);

        object[] customAttributes = memberInfo.GetCustomAttributes(typeof(T), false);
        T attribute = customAttributes.Where(a => a is T).First() as T;
        return attribute;
    }

    private static PropertyInfo GetPropertyInfo(Expression propertySelector)
    {
        Contract.Requires(propertySelector != null, "propertySelector is null.");
        MemberExpression memberExpression = propertySelector as MemberExpression;
        if (memberExpression == null)
        {
            UnaryExpression unaryExpression = propertySelector as UnaryExpression;
            if (unaryExpression != null && unaryExpression.NodeType == ExpressionType.Convert)
            {
                memberExpression = unaryExpression.Operand as MemberExpression;
            }
        }
        if (memberExpression != null && memberExpression.Member.MemberType == MemberTypes.Property)
        {
            return memberExpression.Member as PropertyInfo;
        }
        throw new ArgumentException("No property reference was found.", "propertySelector");
    }

    // Invocation example
    private static Test()
    {
         string table = GetTableName<User>();
         string column = GetColumnName<User>(u=>u.Name);
    }

这篇关于我怎样才能提取数据库表和列名上EF4实体的属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆