8

Code First Migrations を介して作成しようとしている POCO があり、データをシードします。問題は、シード時に特定の値を ID 列に挿入したいことです。

これが私のPOCOです

public class Result
{
    public long ResultId { get; set; }
    public long? TeamId { get; set; }

    public Team Team { get; set; }
}

そして、これが Configuration.cs の Seed メソッドでの AddOrUpdate 呼び出しです。

context.Results.AddOrUpdate
    (
         r => r.ResultId,
         new Result { ResultId = 101, TeamId = null },
         new Result { ResultId = 201, TeamId = null }
    );

予想どおり、101 と 201 の値は挿入されませんが、代わりに 1 と 2 が挿入されます。これを支援するためにモデルに適用できる DataAttributes はありますか?

4

4 に答える 4

19

これは、属性/規則を介してアイデンティティをオフにする方法です

public class Result
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public long ResultId { get; set; }
    public long? TeamId { get; set; }

    public Team Team { get; set; }
}

これは、EntityTypeConfiguration を介して Identity をオフにする方法です

public class ResultMapper : EntityTypeConfiguration<Result>
{
    public ResultMapper()
    {
        HasKey(x => x.ResultId);
        Property(x => x.ResultId)
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
    }
}

または、OnModelCreating オーバーロードを使用できます

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Result>().Property(x => x.ResultId)
               .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
    }
于 2013-03-07T07:06:45.693 に答える
6

誰かがまだ混乱している場合に備えて。. .

IDENTITY_INSERT を Code-First Migration Seed() メソッドで動作させるために必要な追加情報については、以下を参照してください。

Aron のSystem.ComponentModel.DataAnnotations.Schema.DatabaseGenerated属性の実装を使用して、モデル ID の DB 生成プロパティを「なし」に設定しましたが、ID 挿入エラーを回避できませんでした。他の誰かがまだ問題を抱えている場合に備えて、ここに調査結果を投稿すると思いました。

これを機能させるために、シード メソッドのロジックを SQL トランザクションでラップし、メソッドcontext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT myTable ON")を実行する前に挿入を許可していました.AddOrUpdate()。これが私のConfiguration.vbファイルです(サンプルデータとしてGoogle APIタイプの表を使用しています):

Imports System
Imports System.Data.Entity
Imports System.Data.Entity.Migrations
Imports System.Linq

Namespace Migrations

    Friend NotInheritable Class Configuration 
        Inherits DbMigrationsConfiguration(Of DAL.MyDbContext)

        Public Sub New()
            AutomaticMigrationsEnabled = False
            AutomaticMigrationDataLossAllowed = False
        End Sub

        Protected Overrides Sub Seed(context As DAL.MyDbContext)
            '  This method will be called after migrating to the latest version.

            Dim newContext As New MyDbContext(context.Database.Connection.ConnectionString)
            Using ts = newContext.Database.BeginTransaction()

                Try

                    ' Turn on identity insert before updating
                    newContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT GoogleApiTypeGroups ON")
                    ' Make sure the expected GoogleApiTypeGroups exist with the correct names and IDs.
                    newContext.GoogleApiTypeGroups.AddOrUpdate(
                        Function(x) x.Id,
                        New GoogleApiTypeGroup() With {.Id = 1, .name = "Google Cloud APIs"},
                        New GoogleApiTypeGroup() With {.Id = 2, .name = "YouTube APIs"},
                        New GoogleApiTypeGroup() With {.Id = 3, .name = "Google Maps APIs"},
                        New GoogleApiTypeGroup() With {.Id = 4, .name = "Advertising APIs"},
                        New GoogleApiTypeGroup() With {.Id = 5, .name = "Google Apps APIs"},
                        New GoogleApiTypeGroup() With {.Id = 6, .name = "Other popular APIs"},
                        New GoogleApiTypeGroup() With {.Id = 7, .name = "Mobile APIs"},
                        New GoogleApiTypeGroup() With {.Id = 8, .name = "Social APIs"})
                    ' Attempt to save the changes.
                    newContext.SaveChanges()
                    ' Turn off the identity insert setting when done.
                    newContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT GoogleApiTypeGroups OFF")

                    ' Turn on identity insert before updating
                    newContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT GoogleApiTypes ON")
                    ' Make sure the expected GoogleApiTypes exist with the correct names, IDs, and references to their corresponding GoogleApiTypeGroup.
                    newContext.GoogleApiTypes.AddOrUpdate(
                        Function(x) x.Id,
                        New GoogleApiType() With {.Id = 1, .name = "Google Maps JavaScript API", .GoogleApiTypeGroupId = 3})
                    ' Save the changes
                    newContext.SaveChanges()
                    ' Turn off the identity insert setting when done.
                    newContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT GoogleApiTypes ON")

                    ts.Commit()
                Catch ex As Exception
                    ts.Rollback()
                    Throw
                End Try
            End Using

        End Sub

    End Class

End Namespace
于 2016-04-17T21:48:42.990 に答える
3

これを調査した後、キーが以前に作成されていて、[DatabaseGenerated(DatabaseGeneratedOption.None)] を移行に追加すると、実際には意図したとおりに動作しないように見えます。データベース エクスプローラーの [テーブル] -> [キー] に移動して、これを確認できます。 -> PK -> 変更して、ID 仕様が [いいえ] ではなく [はい] に設定されていることを確認します。

この場合は、そのテーブルが存在しないポイントまで移行してから、再度移行してください。

于 2016-05-11T22:26:35.880 に答える