如何更改Entity Framework 6中字符串属性的默认最大长度? [英] How can I change the default max length of string properties in Entity Framework 6?

查看:132
本文介绍了如何更改Entity Framework 6中字符串属性的默认最大长度?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

By default convention, strings properties in an entity model that are not explicitly given a max length are set to nvarchar(max) in the database. We wish to override this convention and give strings a max length of nvarchar(100) if they are not already explicitly set otherwise.

我发现了 PropertyMaxLengthConvention 内置的约定,其描述和文档似乎是我正在寻找的。但是,它不工作,或者我使用它错了,或者它不做我认为它。

I discovered the PropertyMaxLengthConvention built-in convention, which by its description and documentation would seem to be what I am looking for. However, it either doesn't work or I'm using it wrong or it just doesn't do what I think it does.

我已经尝试只是添加约定:

I've tried simply adding the convention:

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

然后我以为也许默认使用了,所以我尝试先删除它: p>

Then I thought maybe the default one is already being used, so I tried removing it first:

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

我甚至尝试明确地在默认情况下添加约定:

I even tried explictly adding the convention before and after the default one:

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

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

No joy. When I add migrations, the columns are still created as nvarchar(max).

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

Is there a way to use that convention to do what I want? If not, can I write a custom convention that will default string properties to nvarchar(100) but will still allow me to explicitly set them to a different value including maxlength?

推荐答案

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

After tracking down the source code for the aforementioned convention, I discovered that it only sets the default max length for properties that are specified to have fixed length. (Bizarre!)

所以我拿起源代码并修改它来创建我自己的约定。现在,具有未指定最大长度的字符串属性将具有默认的最大长度,而不是nvarchar(max)。唯一的缺点是,在 IsMaxLength()配置被明确应用的时候似乎没有一种方法来检测。所以如果我有一个我想要创建为nvarchar(max)的列,我不能使用 IsMaxLength()来实现。

So I took the source code and modified it to create my own convention. Now string properties with unspecified max length will have a default max length instead of being nvarchar(max). The only downside is there doesn't appear to be a way to detect when the IsMaxLength() configuration is explicitly applied. So if I have a column that I do want to have created as nvarchar(max) I can't use IsMaxLength() to do it.

为了解决这个问题,我为StringPropertyConfiguration创建了一个名为 ForceMaxLength()的扩展方法,该方法使用配置属性HasMaxLength(int .MaxValue) - 通常是无效的值,但我可以在我的习惯惯例中轻松测试。当我检测到它时,我只需将MaxLength设置为null,并将IsMaxLength设置为true,并使属性配置继续正常。

To address this, I created an extension method for StringPropertyConfiguration called ForceMaxLength() that configures the property with HasMaxLength(int.MaxValue) - ordinarily an invalid value, but one for which I can easily test in my custom convention. When I detect it, I simply set the MaxLength back to null and set the IsMaxLength to true and let the property configuration continue as normal.

以下是自定义约定: p>

Here's the custom convention:

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);
        }
    }
}

使用方法如下: / p>

Here's how it's used:

using System.Data.Entity.ModelConfiguration;

namespace MyProject.Model.Mapping
{
    public class MyEntityMap : EntityTypeConfiguration<MyEntity>
    {
        public MyEntityMap()
        {
            Property(v => v.StringValue).ForceMaxLength();
        }
    }
}

这篇关于如何更改Entity Framework 6中字符串属性的默认最大长度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆