新的继承类使用EF Code First在迁移时重命名其属性名称

时间:2015-12-08 11:44:10

标签: c# entity-framework inheritance entity-framework-6

我使用实体框架代码优先继承来定义我的类,每个类实现一个抽象类,包含所有它们应具有的公共属性。

当我想要批量添加新的时,我遇到了问题。所有继承的类都具有具有不同类型的公用名的属性,但在最后一个类中,属性也具有相同的类型。

Mirror

到目前为止,事情哪里好。当我添加另一个具有整数Value属性的代码时,通过在SQL表上移动现有的Value列来创建Code First Migration,而不是创建新的,这当然会导致问题,因为我已经在Properties表中有数据。 / p>

func prettyPrint(any: Any) -> String {
    var result = ""
    let m = Mirror(reflecting: any)
    switch m.displayStyle {
    case .Some(.Collection):
        result = "Collection, \(m.children.count) elements"
    case .Some(.Tuple):
        result = "Tuple, \(m.children.count) elements"
    case .Some(.Dictionary):
        result = "Dictionary, \(m.children.count) elements"
    case .Some(.Set):
        result = "Set, \(m.children.count) elements"
    default: // Others are .Struct, .Class, .Enum, .Optional & nil
        result = "\(m.displayStyle)"
    }

    return result
}

prettyPrint([1, 2, 3]) // "Collection, 3 elements"
prettyPrint(NSArray(array:[1, 2, 3])) // "Collection, 3 elements"
prettyPrint(Set<String>()) // "Set, 0 elements"
prettyPrint([1:2, 3:4]) // "Dictionary, 2 elements"
prettyPrint((1, 2, 3)) // "Tuple, 3 elements"
prettyPrint(3) // "nil"
prettyPrint("3") // "nil"

很明显,这在多种方面都是错误的,但我试图更新数据库:

  

错误:新名称&#39; Value2&#39;已经被用作COLUMN名称和   会导致不允许的重复。

从这个行为来看,我理解的是EF开始按类名顺序给出名称和后缀:

  1. Double的价值
  2. Int
  3. 的Value1
  4. String2 for String
  5. 当我尝试将另一个名称以public abstract class ProductProperty { public string CommonProp { get; set; } } public class IntegerProperty : ProductProperty { [Required] public int Value { get; set; } } public class StringProperty : ProductProperty { [Required] public string Value { get; set; } } public class DoubleProperty : ProductProperty { [Required] public double Value { get; set; } } 开头的类添加到批处理中时,它会尝试将其放在Value1之后。

    问题是,带有数字后缀的列名在哪里指向与EF中映射的继承类相同名称的属性?

    也许我可以告诉EF在SQL中添加一个新列并指向正确的类,而不是试图操纵现有的列。

1 个答案:

答案 0 :(得分:2)

我认为您最好通过使用数据注释明确命名Value列,而不是冒着在迁移期间重新分配它们的风险。例如:

public class IntegerProperty : ProductProperty
{
    [Required]
    [Column("Value1")]
    public int Value { get; set; }
}

public class StringProperty : ProductProperty
{
    [Required]
    [Column("Value2")]
    public string Value { get; set; }
}

等等。

或者,您可以使用每个类型的表(TPT)而不是默认的每层次表(TPH),这样每个子类都有自己的表,因此Value将始终被调用{{ 1}}。示例:http://weblogs.asp.net/manavi/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-2-table-per-type-tpt