문제

는 CodeFirst 디자인을 사용하여 새로운 엔티티 프레임 워크 4.1의 객체에 대한 GUID 빗 신원 전략을 구현하는 방법이 있습니까?나는 StoreGeneratedPattern가 작동 할 것이라고 생각했지만 여전히 정상적인 GUID를 제공합니다.

도움이 되었습니까?

해결책

SQL Server를 데이터베이스로 사용하고있는 것 같습니다.이것은 다른 MS 도구간에 불일치의 좋은 예입니다.SQL Server 팀은 newid() 열과 ADO.NET 팀의 기본값으로 UNIQUEIDENTIFIER를 사용하지 않는 것이 좋습니다. 데이터베이스에서 AutoGayerated로 Guid 속성을 지정하는 경우 사용할 수 있습니다.대신 newsequentialid()를 사용해야합니다!

데이터베이스별로 생성 된 순차 GUID를 원한다면 생성 된 테이블을 수정해야하며 자유의 기본 제약 조건을 찾아서 삭제하고, 새 제약 조건을 만들어야하기 때문에 실제로 복잡합니다.이 모든 것은 사용자 정의 데이터베이스 이니셜 라이저에서 수행 할 수 있습니다.여기서 샘플 코드가 있습니다 :

class Program
{

    static void Main(string[] args)
    {
        Database.SetInitializer(new CustomInitializer());
        using (var context = new Context())
        {
            context.TestEntities.Add(new TestEntity() { Name = "A" });
            context.TestEntities.Add(new TestEntity() { Name = "B" });
            context.SaveChanges();
        }
    }
}

public class CustomInitializer : DropCreateDatabaseAlways<Context>
{
    protected override void Seed(Context context)
    {
        base.Seed(context);

        context.Database.ExecuteSqlCommand(@"
            DECLARE @Name VARCHAR(100)

            SELECT @Name = O.Name FROM sys.objects AS O
            INNER JOIN sys.tables AS T ON O.parent_object_id = T.object_id
            WHERE O.type_desc LIKE 'DEFAULT_CONSTRAINT' 
              AND O.Name LIKE 'DF__TestEntities__Id__%'
              AND T.Name = 'TestEntities'

            DECLARE @Sql NVARCHAR(2000) = 'ALTER TABLE TestEntities DROP Constraint ' + @Name

            EXEC sp_executesql @Sql

            ALTER TABLE TestEntities
            ADD CONSTRAINT IdDef DEFAULT NEWSEQUENTIALID() FOR Id");
    }
}

public class TestEntity
{
    public Guid Id { get; set; }
    public string Name { get; set; }
}

public class Context : DbContext
{
    public DbSet<TestEntity> TestEntities { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<TestEntity>()
            .Property(e => e.Id)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    }
}
.

다른 팁

데이터베이스의 GUID 열의 기본값은 전혀 걱정하지 않습니까?다른 값과 같이 클라이언트에 GUID를 생성하지 않는 이유는 무엇입니까?클라이언트 코드에 빗 같은 GUID를 생성하는 방법이 필요합니다.

public static Guid NewGuid()
{
    var guidBinary = new byte[16];
    Array.Copy( Guid.NewGuid().ToByteArray(), 0, guidBinary, 0, 8 );
    Array.Copy( BitConverter.GetBytes( DateTime.Now.Ticks ), 0, guidBinary, 8, 8 );
    return new Guid( guidBinary );
}
.

GUID의 장점 중 하나는 특히 데이터베이스로 왕복없이 클라이언트에서 생성 할 수 있습니다.

가장 간단한 대답

public class User
{
    public User(Guid? id = null, DateTime? created = null)
    {
        if (id != null)
            Id = id;

        if (created != null)
            Created = created;
    }

    public User()
    {
    }

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public DateTime? Created { get; internal set; }

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid? Id { get; internal set; }
}
.

이것은 FluentMigrator 마이그레이션에서 내 케이스에서 관리하는 newsequentialid()의 기본값으로 데이터베이스 테이블을 설정합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top