【问题标题】:Prefix Column Naming Convention in Entity Framework实体框架中的前缀列命名约定
【发布时间】:2018-03-21 22:36:14
【问题描述】:

请考虑 EF6 代码优先数据库。我有:

public class Base
{
    public int Id { get; set; }
}

public class Desc1 : Base
{
    public string Foo { get; set; }
}

public class Desc2 : Base
{
    public int? Foo { get; set; }
}

我希望表 Base 有三列(以自动方式):

Base_Id INT NOT NULL
Desc1_Foo VARCHAR(MAX) NULL
Desc2_Foo INT NULL

我的意思是,以它的类名为前缀。我知道我可以使用EntityTypeConfiguration 来做到这一点,但是我的数据库有 150 个表,我无法配置每一列。

所以我尝试使用命名约定:

public class PrefixConvention : IStoreModelConvention<EdmProperty>
{
    public void Apply(EdmProperty property, DbModel model)
    {
        property.Name = property.DeclaringType.Name + "_" + property.Name;
    }
}

...

modelBuilder.Conventions.Add(new PrefixConvention());

property.DeclaringType.Name 只显示Base 而不是Desc1Desc2,它总是会创建这个:

Base_Id INT NOT NULL
Base_Foo VARCHAR(MAX) NULL
Base_Foo1 INT NULL

我调查了EdmModel 类,但我找不到获取源自表中字段的类名的方法!

【问题讨论】:

  • 这可能会有所帮助:sessionfactory.blogspot.com.eg/2011/04/…
  • 谢谢,但问题是这段代码没有考虑我是否将字段设置为忽略。在这种情况下,这段代码会产生一个异常,因为它试图配置一个在某处被忽略的字段。
  • 不,当然不是。这只是解释我的问题的一个例子。但是我已经解决了,我在下面发布了答案! :)

标签: c# entity-framework entity-framework-6 ef-code-first


【解决方案1】:

好的,我开发了自己的 PrefixConvention。要使用它:

modelBuilder.Conventions.Add(new PrefixConvention());

在这里,PrefixConventionclass:

using System.Collections.Generic;
using System.Data.Entity.Core.Mapping;
using System.Data.Entity.Core.Metadata.Edm;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Linq;

namespace Habitus.Toolkit.Database
{
    public class PrefixConvention : IStoreModelConvention<EdmProperty>
    {
        public void Apply(EdmProperty property, DbModel model)
        {
            if (property.Name == "Id" || property.Name == "Discriminator" || property.DeclaringType.IsView()) return;

            var fragments = model
                .ConceptualToStoreMapping
                .EntitySetMappings
                .SelectMany(esm => esm.EntityTypeMappings)
                .SelectMany(etm => etm.Fragments)
                .Where(f => f.StoreEntitySet.ElementType == property.DeclaringType)
                .ToList();

            var propertyMappings = fragments
                .SelectMany(f => f.PropertyMappings)
                .ToList();

            var path = GetPropertyPath(property, propertyMappings);
            if (path?.Any() == false)
            {
                throw new System.Exception($"Can't process property {property.DeclaringType.FullName}.{property.Name}");
            }

            var first = path.First();
            var names = path.Select(pm => pm.Name).ToList();
            property.Name = $"{first.DeclaringType.Name}__{string.Join("_", names)}";
        }

        private List<EdmProperty> GetPropertyPath(EdmProperty property, List<PropertyMapping> propertyMappings)
        {
            var result = new List<EdmProperty>();

            var scalarPropertyMapping = propertyMappings
                .OfType<ScalarPropertyMapping>()
                .Where(pm => pm.Column == property)
                .FirstOrDefault();

            if (scalarPropertyMapping != null)
            {
                result.Add(scalarPropertyMapping.Property);
            }

            else
            {
                var complexPropertyMappings = propertyMappings
                    .OfType<ComplexPropertyMapping>()
                    .ToList();

                foreach (var complexPropertyMapping in complexPropertyMappings)
                {
                    var recursivePropertyMappings = complexPropertyMapping
                        .TypeMappings
                        .SelectMany(tm => tm.PropertyMappings)
                        .ToList();

                    var recursiveResult = GetPropertyPath(property, recursivePropertyMappings);
                    if (recursiveResult.Any())
                    {
                        result.Add(complexPropertyMapping.Property);
                        result.AddRange(recursiveResult);
                        break;
                    }
                }
            }

            return result;
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-12
    • 1970-01-01
    相关资源
    最近更新 更多