如何更改 Entity Framework 6 中字符串属性的默认最大长度?

2024-02-19

默认情况下,实体模型中未明确给出最大长度的字符串属性设置为nvarchar(max)在数据库中。我们希望覆盖这个约定并给字符串最大长度nvarchar(100)如果尚未明确设置它们。

我发现了PropertyMaxLengthConvention内置约定,从其描述和文档来看,它似乎就是我正在寻找的。然而,它要么不起作用,要么我用错了它,要么它只是没有达到我认为的效果。

我尝试简单地添加约定:

modelBuilder.Conventions.Add(new PropertyMaxLengthConvention(100));

然后我想也许默认的已经被使用了,所以我尝试先删除它:

modelBuilder.Conventions.Remove<PropertyMaxLengthConvention>();
modelBuilder.Conventions.Add(new PropertyMaxLengthConvention(100));

我什至尝试在默认约定之前和之后明确添加约定:

modelBuilder.Conventions.AddBefore<PropertyMaxLengthConvention>(new PropertyMaxLengthConvention(100));
modelBuilder.Conventions.AddAfter<PropertyMaxLengthConvention>(new PropertyMaxLengthConvention(100));

没有喜悦。当我添加迁移时,列仍然创建为nvarchar(max).

有没有办法使用该约定来做我想做的事?如果没有,我可以编写一个自定义约定,将默认字符串属性设置为nvarchar(100)但仍然允许我明确地将它们设置为不同的值,包括 maxlength?


在跟踪上述约定的源代码后,我发现它只为指定为固定长度的属性设置默认最大长度。 (奇怪!)

因此,我获取了源代码并对其进行了修改以创建我自己的约定。现在,未指定最大长度的字符串属性将具有默认的最大长度,而不是 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();
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何更改 Entity Framework 6 中字符串属性的默认最大长度? 的相关文章

随机推荐