我有一个本应很简单的问题,但我自己一直找不到答案。
我正在使用EF4 CTP-5代码第一模型与手动生成的POCOs。它将生成的SQL中的字符串比较处理为
WHERE N'Value' = Object.Property
我知道我可以使用以下命令覆盖此功能:
[Column(TypeName = "varchar")]
public string Property {get;set;}
它修复了该单次出现的问题,并将SQL正确生成为:
WHERE 'Value' = Object.Property
然而,我正在处理一个非常大的域模型,遍历每个字符串字段并设置TypeName = "varchar“将是非常非常繁琐的。我想指定EF应将字符串视为全面的varchar,因为这是此数据库中的标准,而nvarchar是例外情况。
想要纠正这一点的推理就是查询执行效率。在SQL Server 2k5中,varchar和nvarchar之间的比较效率非常低,其中varchar到varchar的比较几乎是立即执行的。
发布于 2011-02-25 05:23:54
在EF 4.1之前,您可以使用约定并将以下约定添加到ModelBuilder中:
using System;
using System.Data.Entity.ModelConfiguration.Configuration.Properties.Primitive;
using System.Data.Entity.ModelConfiguration.Conventions.Configuration;
using System.Reflection;
public class MakeAllStringsNonUnicode :
IConfigurationConvention<PropertyInfo, StringPropertyConfiguration>
{
public void Apply(PropertyInfo propertyInfo,
Func<StringPropertyConfiguration> configuration)
{
configuration().IsUnicode = false;
}
}
(摘自http://blogs.msdn.com/b/adonet/archive/2011/01/10/ef-feature-ctp5-pluggable-conventions.aspx)
更新: 4.1版本中删除了可插拔的约定。另一种方法的Check my blog )
发布于 2012-09-11 02:00:34
我扩展了Marc Cals的答案(和Diego的博客文章),根据问题将所有实体上的所有字符串全局设置为非unicode,而不是必须按类手动调用。见下文。
/// <summary>
/// Change the "default" of all string properties for a given entity to varchar instead of nvarchar.
/// </summary>
/// <param name="modelBuilder"></param>
/// <param name="entityType"></param>
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);
}
/// <summary>
/// Return an enumerable of all DbSet entity types in "this" context.
/// </summary>
/// <param name="a"></param>
/// <returns></returns>
private IEnumerable<Type> GetEntityTypes()
{
return this
.GetType().GetProperties()
.Where(a => a.CanWrite && a.PropertyType.IsGenericType && a.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>))
.Select(a => a.PropertyType.GetGenericArguments().Single());
}
最后,从您的OnModelCreating(DbModelBuilder ModelBuilder)调用它:
foreach (var entityType in GetEntityTypes())
SetAllStringPropertiesAsNonUnicode(modelBuilder, entityType);
发布于 2012-04-30 05:58:36
在Diego的博客帮助下,在不使用anotations的情况下创建POCO varchar的公共属性是:
private void SetStringPropertiesAsNonUnicode<e>(DbModelBuilder _modelBuilder) where e:class
{
//Indiquem a totes les propietats string que no són unicode per a que es crein com a varchar
List<PropertyInfo> stringProperties = typeof(e).GetProperties().Where(c => c.PropertyType == typeof(string) && c.PropertyType.IsPublic).ToList();
foreach (PropertyInfo propertyInfo in stringProperties)
{
dynamic propertyExpression = GetPropertyExpression(propertyInfo);
_modelBuilder.Entity<e>().Property(propertyExpression).IsUnicode(false);
}
}
// Edit: Also stole this from referenced blog post (Scott)
static LambdaExpression GetPropertyExpression(PropertyInfo propertyInfo)
{
var parameter = Expression.Parameter(propertyInfo.ReflectedType);
return Expression.Lambda(Expression.Property(parameter, propertyInfo), parameter);
}
https://stackoverflow.com/questions/5109170
复制相似问题