前段时间我提出了一个问题about creating a custom convention for EF6,提供的答案非常顺利。
现在,我遇到了一个我正在使用它的情况,并希望覆盖特定列的值,但无法找到如何执行此操作。
这是我添加的惯例:
class ColumnPrefixConvention : IStoreModelConvention<EdmProperty>
{
public void Apply(EdmProperty property, DbModel model) {
string name = property.Name;
// check if this is an ID field
if (name == "ID") {
return;
}
// Check if this is a foreignID field
if (name.Right(2) == "ID") {
return;
}
property.Name = property.DeclaringType.Name + property.Name;
}
}
这是模型构建者:
protected override void OnModelCreating(DbModelBuilder mb) {
mb.Conventions.Add(new ColumnPrefixConvention());
mb.Entity<ClientRate>().Property(x => x.Rate).HasColumnName("HourlyRate");
mb.Entity<ClientRate>().Property(x => x.EffectiveDate).HasColumnName("EffectiveDate");
}
正如您所看到的,我正在尝试覆盖不遵循惯例的HourlyRate
和EffectiveDate
列。
我原本以为在实体属性级别指定HasColumnName
将优先于约定,但事实并非如此:我收到一个无效列名错误,表明它仍在尝试使用前缀我添加的ColumnPrefixConvention的表名。
有没有人知道解决这个问题的方法?感谢
答案 0 :(得分:2)
EF并不真正了解你的约定,所以它总是运行。但是在将显式配置应用于模型后,它将运行。如下所示:
if (property.MetadataProperties.Contains("Configuration"))
{
//check if ColumnName has been explicitly configured
object value = property.MetadataProperties["Configuration"].Value;
if (value.GetType().GetProperties().Where(p => p.Name == "ColumnName").Any())
{
return;
}
}
答案 1 :(得分:0)
David Browne的代码检查是否存在ColumnName属性,但是例如,如果设置了列MaxLength属性,则该字段可以为null。
如果调用此属性的get方法,则可以获取实际名称-然后检查其是否为空。
类似:-
string GetExplicitlySetColumnName(EdmProperty item)
{
// have we a configuration item
if (item.MetadataProperties.Contains("Configuration"))
{
// get the configuration for this item
var configuration = item.MetadataProperties["Configuration"].Value;
// get the property info for the ColumnName property if we have one
var properyInfo = configuration.GetType().GetProperty("ColumnName");
if (properyInfo != null)
{
// if we have a column name property, return the value
if (properyInfo.GetMethod.Invoke(configuration, null) is String columnName)
{
return columnName;
}
}
}
return null;
}