17

Entity Framework 6.1 では、新しいHasColumnAnnotationメソッドを介してテーブル インデックスを作成する機能が追加されたようです。プロセスを高速化するために、いくつかのヘルパー拡張機能を作成しました。

public static class MappingExtensions
{
    public static StringPropertyConfiguration HasIndex(this StringPropertyConfiguration config, bool isUnique = false)
    {
        return config.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute() { IsUnique = isUnique }));
    }
    public static StringPropertyConfiguration HasIndex(this StringPropertyConfiguration config, string name, int order = 1, bool isUnique = false)
    {
        return config.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute(name, order) { IsUnique = isUnique }));
    }
    public static PrimitivePropertyConfiguration HasIndex(this PrimitivePropertyConfiguration config, bool isUnique = false)
    {
        return config.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute() { IsUnique = isUnique }));
    }
    public static PrimitivePropertyConfiguration HasIndex(this PrimitivePropertyConfiguration config, string name, int order = 1, bool isUnique = false)
    {
        return config.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute(name, order) { IsUnique = isUnique }));
    }
}

これはうまく機能します...別のインデックスで既に使用されている列を含む2番目のインデックスを作成しようとするまで。最後に追加したものは、オリジナルを上書きします。とHasColumnAnnotationで利用可能な新しいものを介して、同じ列に複数のインデックスを現在追加できるかどうかを知っている人はいますか?StringPropertyConfigurationPrimitivePropertyConfiguration

移行スクリプトに手動でインデックスを追加することで、いつものようにこれを回避できますが、EntityTypeConfigurationマッピングでこれを構成できると、すべてを 1 か所にまとめることができます。


Gerts のフィードバックの後、これが私が最終的に行ったことです。

public static class MappingExtensions
{
    public static StringPropertyConfiguration HasIndex(this StringPropertyConfiguration config, params IndexAttribute[] indexes)
    {
        return config.HasColumnAnnotation("Index", new IndexAnnotation(indexes));
    }

    public static PrimitivePropertyConfiguration HasIndex(this PrimitivePropertyConfiguration config, params IndexAttribute[] indexes)
    {
        return config.HasColumnAnnotation("Index", new IndexAnnotation(indexes));
    }
}

そして、ここに新しい使い方があります:

Property(x => x.Name).IsRequired().HasMaxLength(65).HasIndex(new IndexAttribute("IX_Countries_Name") { IsUnique = true }, new IndexAttribute("IX_Countries_Published", 2))
4

1 に答える 1

31

これは、各拡張メソッドが新しい注釈をプロパティに割り当て、前の注釈を上書きするためです。例であなたの方法を使用してそれを示しましょう。

この(役に立たない)クラスがあるとしましょう

public class Client
{
    public int ClientId { get; set; }
    public int CompanyId { get; set; }
    public int AddressId { get; set; }
}

そして、インデックス定義を適用します (一部をスキップしますmodelBuilder.Entity<Client>()):

.Property(c => c.ClientId).HasIndex("ClientCompanyIndex");
.Property(c => c.CompanyId).HasIndex("ClientCompanyIndex", 2);
.Property(c => c.ClientId).HasIndex("ClientAddressIndex");
.Property(c => c.AddressId).HasIndex("ClientAddressIndex", 2);

拡張メソッドをインライン化すると (Resharper に感謝します)、これは次のようになります。

.Property(c => c.ClientId).HasColumnAnnotation("Index",
    new IndexAnnotation(new IndexAttribute("ClientCompanyIndex", 1));
.Property(c => c.CompanyId).HasColumnAnnotation("Index",
     new IndexAnnotation(new IndexAttribute("ClientCompanyIndex", 2));
.Property(c => c.ClientId).HasColumnAnnotation("Index",
    new IndexAnnotation(new IndexAttribute("ClientAddressIndex", 1));
.Property(c => c.AddressId).HasColumnAnnotation("Index",
     new IndexAnnotation(new IndexAttribute("ClientAddressIndex", 2));

これは書くことと同じです。

[Index("ClientCompanyIndex", Order = 1)]
public int ClientId { get; set; }

そしてそれ

[Index("ClientAddressIndex", Order = 1)]
public int ClientId { get; set; }

正しい注釈を再現するには...

[Index("ClientAddressIndex", IsUnique = true, Order = 1)]
[Index("ClientCompanyIndex", IsUnique = true, Order = 1)]
public int ClientId { get; set; }
[Index("ClientCompanyIndex", IsUnique = true, Order = 2)]
public int CompanyId { get; set; }
[Index("ClientAddressIndex", IsUnique = true, Order = 2)]
public int AddressId { get; set; }

...ClientIdプロパティの構成は次のようになります

.Property(c => c.ClientId).HasColumnAnnotation("Index",
    new IndexAnnotation(new[]
        {
            new IndexAttribute("ClientCompanyIndex", 1),
            new IndexAttribute("ClientAddressIndex", 1)
        }));

いきなり拡張メソッドを作成することは、あまり魅力的ではなくなりました。この結合されたアノテーション用に 1 つ作成する努力はほとんど価値がありません。しかし、使い捨てカラムの場合、メソッドは改善されます。

もちろん、なぜこれを試しているのかは明らかです。現在の流暢な構文は、控えめに言っても不格好です。EF チームはこのことをよく知っており、貢献者がすぐにこの問題を解決してくれることを望んでいます。多分あなたのための何か?

于 2014-06-21T22:48:04.163 に答える