.net 循环实体列映射以转换列名
我想对EntityFramework5中的大量列应用一个转换,而不必显式地将它们全部键入。作为一个例子,我想在50多列中将PascalCase转换为下划线大小写.net 循环实体列映射以转换列名,.net,entity-framework,entity-framework-5,ef-fluent-api,.net,Entity Framework,Entity Framework 5,Ef Fluent Api,我想对EntityFramework5中的大量列应用一个转换,而不必显式地将它们全部键入。作为一个例子,我想在50多列中将PascalCase转换为下划线大小写 modelBuilder.Entity<Department>() .Property(t => t.DepartmentName) .HasColumnName("DEPARTMENT_NAME"); 编辑: 这与类似,但对我不起作用。也许这对EF5有不同的要求
modelBuilder.Entity<Department>()
.Property(t => t.DepartmentName)
.HasColumnName("DEPARTMENT_NAME");
编辑:
这与类似,但对我不起作用。也许这对EF5有不同的要求
使用@appect的答案,我尝试了以下修改,但语法不太正确。我是EF新手,因此不熟悉如何将旧语法转换为新语法
modelBuilder.Entity<Job>()
.Map(m =>
{
m.Properties<Job>(e => e.HasColumnName(name => RegEx.Replace(name, "(?<=.)(?=[A-Z])", "_").ToUpper()));
});
您可以使用DbModelBuilder的Properties方法。将pascal大小写模式轻松转换为下划线模式,如下所示:
modelBuilder.Properties()
.Configure(e => e.HasColumnName(Regex.Replace(e.ClrPropertyInfo.Name, "(?<=.)(?=[A-Z])", "_").ToUpper());
public PropertyTransformConvention()
{
Properties()
.Configure(c => c.Transform(s => Regex.Replace(input: s, pattern: "([A-Z])([A-Z][a-z])|([a-z0-9])([A-Z])", replacement: "$1$3_$2$4").ToUpper()));
}
注意:上面的代码只适用于直接属性,如果您有一些复杂属性返回一些ComplexType,那么它将不起作用。从技术上讲,您需要从实体的属性中排除所有返回ComplexType的属性,然后如果可能的话,将ComplexType的属性与实体的直接属性合并,然后再遍历所有属性并配置每个属性
PS:我不确定Dapper.FluentMap是否支持EF5,但从您发布的代码来看,添加ToUpper方法非常简单,如下所示:
modelBuilder.Properties()
.Configure(e => e.HasColumnName(Regex.Replace(e.ClrPropertyInfo.Name, "(?<=.)(?=[A-Z])", "_").ToUpper());
public PropertyTransformConvention()
{
Properties()
.Configure(c => c.Transform(s => Regex.Replace(input: s, pattern: "([A-Z])([A-Z][a-z])|([a-z0-9])([A-Z])", replacement: "$1$3_$2$4").ToUpper()));
}
我尝试访问Dapper.FluentMap的主页,看起来它有一些基于约定的类。如果这是来自EF的,那么它只有在EF6之后才受支持。所以我不确定这个简洁的代码在EF5中是否有效。如果可行,你应该尝试上面的代码以方便使用。我就是这样解决的。我的目标是将camelCase约定仅应用于特定的表/实体表客户机
modelBuilder.Properties().Configure(p => p.HasColumnName(GetDBName(p, p.ClrPropertyInfo.Name)));
private string GetDBName(ConventionPrimitivePropertyConfiguration p, string name)
{
var result = name;
var entityName = p.ClrPropertyInfo.ReflectedType.UnderlyingSystemType.Name;
if (entityName == "Client")
result = Helper.CamelCaseParaSnakeCaseOracle(name);
return result;
}
static public string CamelCaseParaSnakeCaseOracle(string input)
{
return Regex.Replace(input,
@"(?:\b|(?<=([A-Za-z])))([A-Z][a-z]*)",
m => string.Format(@"{0}{1}",
(m.Groups[1].Value.Length > 0) ? "_" : "", m.Groups[2].Value.ToUpper()));
}
看起来不错,但modelBuilder没有属性方法。我已经更新了问题,包括我如何尝试使用你的答案,但语法不正确。关于你的编辑,这正是我在问题中所做的。问题是e.HasColumnName抛出错误,因为它不是作业类型的方法。此外,您的用户名完美地完成了您的注释@麦克阿瑟,我刚做完。你应该试着自己理解代码,我对它的注释相当清楚,也许可以进一步改进它。代码还没有经过测试,但应该可以工作。事实上,我只是针对一个简单的实体类型运行了它。这是我能想到的EF5的唯一方法。正如我在我的PS中所说的,你也应该考虑DopeP.FruttMax。我不会尝试改进我张贴的代码,这是你的一部分。太棒了!我会尽快查出来的。巨大的道具给你的工作和后续行动!我非常感激!令人惊讶的是,EF6中如此简单的操作会给EF5带来如此多的麻烦。再次感谢!