前段时间我问了一个关于为 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
会优先于约定,但事实并非如此:我收到一个无效的列名错误,表明它仍在尝试根据我添加的列前缀约定为表名添加前缀。
有谁知道解决这个问题的方法? 谢谢
并不真正知道你的约定是做什么的,所以它总是运行。 但它在将显式配置应用于模型后运行。 所以像这样:
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;
}
}
David Browne 的代码检查是否存在 ColumnName 属性,但如果设置了 Columns MaxLength 属性,则此属性可能为 null。
如果调用此属性的 get 方法,则可以获取实际名称 - 然后检查它是否为 null。
像这样:-
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;
}