实体框架v4和列名称中的下划线

时间:2011-03-29 22:25:15

标签: .net entity-framework

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

Order._activity

成为实体属性:

Order.C_activity

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

  

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

这是具有相关应用程序的旧数据库,因此无法更改数据库中的列名称。

感谢您的任何意见。

2 个答案:

答案 0 :(得分:1)

好的,我没有针对您的确切解决方案,但情况类似。如果在引用另一个表时,EF生成的字段以ID结尾。例。表人员有一列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所有。

答案 1 :(得分:1)

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

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

但是,有一点需要注意:由于Microsoft客户端代理生成器使用EdmItemCollection在生成期间解析元数据,因此尝试生成代理(例如在Visual Studio中)对于具有以下划线开头的实体属性的服务失败。您需要在没有其中一个代理生成器的帮助下从此类服务中使用OData。