EF Code First - Globally set varchar mapping over nvarchar

后端 未结 4 1042
广开言路
广开言路 2020-12-14 19:39

I have what should be an easy question but I have been unable to find the answer myself.

I am using EF4 CTP-5 Code First Model with hand generated POCOs. It is proc

4条回答
  •  Happy的楠姐
    2020-12-14 20:12

    I extended Marc Cals' answer (and Diego's blog post) to globally set all strings on all entities as non-unicode as per the question, rather than having to call it manually per-class. See below.

    /// 
    /// Change the "default" of all string properties for a given entity to varchar instead of nvarchar.
    /// 
    /// 
    /// 
    protected void SetAllStringPropertiesAsNonUnicode(
        DbModelBuilder modelBuilder,
        Type entityType)
    {
        var stringProperties = entityType.GetProperties().Where(
            c => c.PropertyType == typeof(string)
               && c.PropertyType.IsPublic 
               && c.CanWrite
               && !Attribute.IsDefined(c, typeof(NotMappedAttribute)));
    
        foreach (PropertyInfo propertyInfo in stringProperties)
        {
            dynamic propertyExpression = GetPropertyExpression(propertyInfo);
    
            MethodInfo entityMethod = typeof(DbModelBuilder).GetMethod("Entity");
            MethodInfo genericEntityMethod = entityMethod.MakeGenericMethod(entityType);
            object entityTypeConfiguration = genericEntityMethod.Invoke(modelBuilder, null);
    
            MethodInfo propertyMethod = entityTypeConfiguration.GetType().GetMethod(
                "Property", new Type[] { propertyExpression.GetType() });
    
            StringPropertyConfiguration property = (StringPropertyConfiguration)propertyMethod.Invoke(
                entityTypeConfiguration, new object[] { propertyExpression });
            property.IsUnicode(false);
        }
    }
    
    private static LambdaExpression GetPropertyExpression(PropertyInfo propertyInfo)
    {
        var parameter = Expression.Parameter(propertyInfo.ReflectedType);
        return Expression.Lambda(Expression.Property(parameter, propertyInfo), parameter);
    }
    
    /// 
    /// Return an enumerable of all DbSet entity types in "this" context.
    /// 
    /// 
    /// 
    private IEnumerable GetEntityTypes()
    {
        return this
            .GetType().GetProperties()
            .Where(a => a.CanWrite && a.PropertyType.IsGenericType && a.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>))
            .Select(a => a.PropertyType.GetGenericArguments().Single());
    }
    

    Finally, call it from your OnModelCreating(DbModelBuilder modelBuilder):

    foreach (var entityType in GetEntityTypes())
        SetAllStringPropertiesAsNonUnicode(modelBuilder, entityType);
    

提交回复
热议问题