Как сначала реализовать параллелизм в коде EF при использовании иерархии TPT - PullRequest
1 голос
/ 08 апреля 2011

Привет всем! Я пытаюсь реализовать оптимистическую проверку параллелизма сначала с помощью Entity Framework Code (установленного через nuget, поэтому я предполагаю, что это последний RC). Тем не менее, я не могу заставить его работать. У меня есть следующая иерархия классов

public abstract class DbEntityBase
{
    /// <summary>
    /// Autogenerated primary key for the object
    /// </summary>
    public Guid Id { get; private set; }

    protected DbEntityBase()
    {
        Id = Guid.NewGuid();
    }

    //Some override for equality, omitted for brievity
}

public class Drawing : DbEntityBase
{
    public string Name { get; set; }

    //Just an implementation of ICollection<DrawingVersion>
    public DrawingVersionCollection Versions { get; private set; }

    public Drawing()
    {
        Name = "New Drawing";
        Versions = new DrawingVersionCollection(this);         
    }

}

public class DrawingVersion : DbEntityBase
{
    public string Name { get; set; }

    public DateTime Started { get; set; }

    public DateTime LastModified { get; set; }

    public DrawingFile File { get; private set; }

    public Drawing Owner { get; internal set; }

    internal DrawingVersion()
    {
        Name = "New Version";
        Started = DateTime.Now;
        LastModified = DateTime.Now;
        File = new DrawingFile();
    }
}

Я использую следующий DbContext, чтобы сохранить их

public class PortfolioContext : DbContext
{
    public DbSet<Drawing> Drawings { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        //Key mapping
        modelBuilder.Entity<DbEntityBase>()
            .HasKey(e => e.Id);

        //Table Mapping
        modelBuilder.Entity<DrawingVersion>().ToTable("DrawingVersion");
        modelBuilder.Entity<Drawing>().ToTable("Drawing");

        //Ignored fields
        modelBuilder.Entity<DrawingVersion>()
            .Ignore(v => v.Owner);
    }
}

Все это работает отлично и денди. Если я проверю сгенерированную схему, я увижу таблицу, одну для рисования и одну для DrawingVersion. Я могу читать, обновлять и удалять без проблем.

Проблема возникла, когда я захотел добавить метку времени к своим сущностям. Сначала я сделал наивную вещь. Я добавил следующее в DbEntityBase

    public byte[] Timestamp { get; set; }

И эти строки в моем контексте

        //Versionning mapping
        modelBuilder.Entity<DbEntityBase>()
            .Property(e => e.Timestamp)
            .IsConcurrencyToken()
            .HasColumnType("timestamp")
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);

Однако во время генерации схемы произошла ошибка со следующим исключением

System.NotSupportedException: хранить сгенерированный шаблон 'Computed' является не поддерживается для свойств, которые не типа «отметка времени» или 'Rowversion'.

В тот момент я был немного сакралистичен. «Ну и дела, это просто так, я поставил метка времени в типе столбца, в то время как я должен был бы вместо этого поставить метку времени ». Вместо этого я попытался поставить 'rowversion', но она все еще не работала. Я также попытался использовать атрибут TimestampAttribute непосредственно для свойства, но та же ошибка.

Я пытался поместить данные метки времени в дочерние классы, но затем я выбрал следующее исключение

System.Data.Entity.ModelConfiguration.ModelValidationException : Одна или несколько ошибок проверки были обнаружено при генерации модели

System.Data.Edm.EdmEntityType :: Тип Portfolio.Repositories.Drawing является происходит от типа 'Portfolio.Repositories.DbEntityBase' это тип для EntitySet 'PortfolioContext.DbEntityBases'. Тип 'Portfolio.Repositories.Drawing' определяет новые требования к параллелизму которые не допускаются для подтипов базовые типы EntitySet.

Так что, думаю, я тоже не могу этого сделать.

Должен сказать, я очень смущен. Почему исключение говорит мне, что я должен использовать метку времени, поскольку это именно то, что я делаю? Может ли это быть ошибкой в ​​рамках? Если нет, есть ли другой способ добавить проверку параллелизма с отображением типа таблицы?

Я использую SQL Serve Ce 4.0 в качестве базы данных.

1 Ответ

1 голос
/ 11 апреля 2011

Это похоже на проблему в определении наследования TPC.Вы должны изменить сопоставление дочерних сущностей, чтобы использовать сопоставление из родительской сущности:

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

    modelBuilder.Entity<DrawingVersion>()
                .Map(m => m.MapInheritedProperties())
                .ToTable("DrawingVersion");

    modelBuilder.Entity<Drawing>()
                .Map(m => m.MapInheritedProperties())
                .ToTable("Drawing");

    ...
}
...