【问题标题】:Entity Framework v4 and underscores in column namesEntity Framework v4 和列名中的下划线
【发布时间】:2011-04-02 00:42:01
【问题描述】:

对于 Entity Framework v4 如何支持带有下划线前缀的列名的问题,是否有人找到了解决方案或变通方法?我注意到 EFv4 创建的实体上的属性将下划线前缀替换为“C_”前缀。因此,例如数据库列:

Order._activity

成为实体属性:

Order.C_activity

然后,当我尝试查询时,我可以理解地得到错误:

数据读取器不兼容 指定的“CorporateModel.Order”。 类型的成员,“C_activity”, 没有对应的列 在同名数据阅读器中。

这是一个带有依赖应用程序的旧数据库,因此不能更改数据库中的列名。

感谢您的任何意见。

【问题讨论】:

    标签: .net entity-framework


    【解决方案1】:

    好的,我没有给你确切的解决方案,但有类似的情况。如果引用另一个表时,EF 生成的字段以 ID 结尾。例子。表 Person 有一个列 JobID 而不是 Job。我们不喜欢那样。这就是问题所在:http://social.msdn.microsoft.com/Forums/en-US/adonetefx/thread/f8ddb2be-78c9-4296-b293-37b7bc8e8fd7

    所以我的队友所做的就是“覆盖”默认约定。如果这不完全是您的情况,请原谅。我认为它应该给你一些提示。这是 EF V 4.1

     public class ASRCDb : DbContext, IUnitOfWork
    {
        public void Complete()
        {
            SaveChanges();
        }
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
            modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
            AddAllEntities(modelBuilder);
        }
    
        static void AddAllEntities(DbModelBuilder modelBuilder)
        {
            var entity = typeof(DbModelBuilder).GetMethod("Entity");
            foreach (var entityType in GetEntityTypes())
            {
                var entityTypeConfiguration = entity.MakeGenericMethod(entityType).Invoke(modelBuilder, null);
                foreach (var propertyInfo in GetReferenceProperties(entityType))
                    ConfigureRelationship(propertyInfo, entityTypeConfiguration);
            }
        }
    
        static IEnumerable<PropertyInfo> GetReferenceProperties(Type entityType)
        {
            return entityType.GetProperties().Where(p => typeof(IEntity).IsAssignableFrom(p.PropertyType));
        }
    
        static IEnumerable<Type> GetEntityTypes()
        {
            return typeof(Entity).Assembly.GetTypes().Where(type => type.IsClass && !type.IsAbstract);
        }
    
        static void ConfigureRelationship(PropertyInfo propertyInfo, dynamic entityTypeConfiguration)
        {
            var required = propertyInfo.GetCustomAttributes(typeof(RequiredAttribute), true).Any();
            var navigation = required
                                 ? entityTypeConfiguration.HasRequired(GetPropertyExpression(propertyInfo))
                                 : entityTypeConfiguration.HasOptional(GetPropertyExpression(propertyInfo));
            UsePropertyNameAsColumnName(propertyInfo, navigation);
        }
    
        static void UsePropertyNameAsColumnName(PropertyInfo propertyInfo, dynamic navigation)
        {
            Action<ForeignKeyAssociationMappingConfiguration> mapKey = x => x.MapKey(propertyInfo.Name);
            navigation.WithMany().Map(mapKey);
        }
    
        static dynamic GetPropertyExpression(PropertyInfo propertyInfo)
        {
            var parameter = Expression.Parameter(propertyInfo.ReflectedType);
            return Expression.Lambda(
                typeof(Func<,>).MakeGenericType(propertyInfo.ReflectedType, propertyInfo.PropertyType),
                Expression.Property(parameter, propertyInfo),
                parameter);
        }
    }
    

    所有功劳都归功于我的好友 Diego Mijelshon。

    【讨论】:

    • 感谢您的回复。我考虑过某种类型的覆盖,但不确定覆盖这个特定问题(下划线“转换”)是否只是覆盖约定或实际上可能导致事情中断。我将研究一下您的代码中显示的方法,看看它是否适用于我的情况。
    • 我可能会误解,但似乎这种方法在生成数据库时会起作用。我要反过来:从现有数据库生成模型,所以我不确定它是否适用。我现在正在考虑将 ADO.NET EntityObject Generator 添加到我的项目中并修改 .tt 文件以生成代码。欢迎提供其他 cmets/答案。
    • 啊,我误解了整个事情是我的错误。我没有使用模板生成代码的经验,但我读过它是可扩展的。祝你好运
    • 我开始认为这是不可能的。如果我尝试直接在模型浏览器中更改属性名称,使其以下划线开头,则会因“无效名称”错误而被拒绝。所以,我怀疑即使我设法用 T4 模板更改它,我也会遇到问题。
    • 我采用了另一种解决方案:使用 LINQ to SQL 构建模型而不是 EF,然后使用反射提供程序在模型上实现 IQueryable/IUpdatable(请参阅here),以便我可以公开它通过 WCF 数据服务。保持我的下划线完好无损,似乎工作正常。 @Markust 我会采纳你的建议来解决我原来的问题。互动+1。谢谢。
    【解决方案2】:

    似乎 EF 不支持以下划线开头的属性名称,这是 EDM 模式强制执行的模式约束。一个例子是SSDL schema

    我采用了另一种解决方案:使用 LINQ to SQL 而不是 EF 来构建模型,然后使用反射提供程序在模型上实现 IQueryable/IUpdatable(请参阅here),以便我可以通过 WCF 数据服务公开它.这使模型和从服务返回的结果 OData 中的下划线保持不变。

    但是,有一个警告:由于 Microsoft 客户端代理代码生成器在生成过程中使用 EdmItemCollection 解析元数据,因此对于具有以下划线开头的实体属性的服务,尝试生成代理(例如在 Visual Studio 中)会失败。您需要在没有这些代理生成器的帮助的情况下使用此类服务​​中的 OData。

    【讨论】:

      猜你喜欢
      • 2012-01-24
      • 2016-08-08
      • 1970-01-01
      • 2018-02-01
      • 1970-01-01
      • 2020-06-18
      • 1970-01-01
      • 2011-04-12
      • 1970-01-01
      相关资源
      最近更新 更多