在跟踪上述约定的源代码后,我发现它只为指定为固定长度的属性设置了默认的最大长度。(奇怪!)
因此,我获取了源代码并对其进行了修改以创建自己的约定。现在,具有未指定最大长度的字符串属性将具有默认的最大长度,而不是 nvarchar(max)。唯一的缺点是似乎没有一种方法可以检测何时IsMaxLength()
显式应用配置。因此,如果我有一个我确实想创建为 nvarchar(max) 的列,我将无法使用IsMaxLength()
它来创建它。
为了解决这个问题,我为 StringPropertyConfiguration 创建了一个名为的扩展方法,该方法ForceMaxLength()
使用 - 通常为无效值配置属性HasMaxLength(int.MaxValue)
,但我可以在自定义约定中轻松对其进行测试。当我检测到它时,我只需将 MaxLength 设置回 null 并将 IsMaxLength 设置为 true 并让属性配置继续正常进行。
这是自定义约定:
using System;
using System.Collections.Generic;
using System.Data.Entity.Core.Metadata.Edm;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.ModelConfiguration.Conventions;
namespace MyProject.CustomConventions
{
public class CustomPropertyMaxLengthConvention : IConceptualModelConvention<EntityType>, IConceptualModelConvention<ComplexType>
{
private const int DefaultLength = 128;
private readonly int length;
public CustomPropertyMaxLengthConvention()
: this(DefaultLength)
{
}
public CustomPropertyMaxLengthConvention(int length)
{
if (length <= 0)
{
throw new ArgumentOutOfRangeException("length", "Invalid Max Length Size");
}
this.length = length;
}
public virtual void Apply(EntityType item, DbModel model)
{
SetLength(item.DeclaredProperties);
}
public virtual void Apply(ComplexType item, DbModel model)
{
SetLength(item.Properties);
}
private void SetLength(IEnumerable<EdmProperty> properties)
{
foreach (EdmProperty current in properties)
{
if (current.IsPrimitiveType)
{
if (current.PrimitiveType == PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String))
{
SetStringDefaults(current);
}
if (current.PrimitiveType == PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Binary))
{
SetBinaryDefaults(current);
}
}
}
}
private void SetStringDefaults(EdmProperty property)
{
if (property.IsUnicode == null)
{
property.IsUnicode = true;
}
SetBinaryDefaults(property);
}
private void SetBinaryDefaults(EdmProperty property)
{
if (property.MaxLength == int.MaxValue)
{
property.MaxLength = null;
property.IsMaxLength = true;
}
else if (property.MaxLength == null || !property.IsMaxLength)
{
property.MaxLength = length;
}
}
}
}
这是扩展方法:
using System.Data.Entity.ModelConfiguration.Configuration;
namespace MyProject.Model.Mapping
{
public static class MappingExtensions
{
public static void ForceMaxLength(this StringPropertyConfiguration obj)
{
obj.HasMaxLength(int.MaxValue);
}
}
}
以下是它的使用方法:
using System.Data.Entity.ModelConfiguration;
namespace MyProject.Model.Mapping
{
public class MyEntityMap : EntityTypeConfiguration<MyEntity>
{
public MyEntityMap()
{
Property(v => v.StringValue).ForceMaxLength();
}
}
}