Вопрос по моделированию домена с использованием C # с Entity Framework CTP 4 - PullRequest
6 голосов
/ 05 декабря 2010

Я пытаюсь смоделировать альбом, в котором есть коллекция фотографий.В каждом альбоме будет коллекция фотографий и фотография большого пальца.Это то, что у меня есть, но EF, похоже, не нравится:

public class Album : IEntity {
        private DateTime _dateCreated;

        public Album() {
            _dateCreated = SystemTime.Now();
            Photos = new List<Photo>();
        }
        public long Id { get; set; }
        public string Name { get; set; }
        public string Location { get; set; }
        public DateTime DateCreated
        {
            get { return _dateCreated; }
            set { _dateCreated = value; }
        }
        public virtual Site Site { get; set; }
        public virtual Photo Thumbnail { get; set; }
        public virtual ICollection<Photo> Photos { get; set; }
    }

public class Photo : IEntity {
            public Photo() {
                _dateCreated = SystemTime.Now();
            }
            private DateTime _dateCreated;
            public long Id { get; set; }
            public string Caption { get; set; }
            public string FileName { get; set; }
            public DateTime DateCreated
            {
                get { return _dateCreated; }
                set { _dateCreated = value; }
            }
            public virtual Album Album { get; set; }

        }

 public class AlbumMap : EntityConfiguration<Album>
    {
        public AlbumMap()
        {
            HasKey(x => x.Id);
            Property(x => x.Id).IsIdentity();
            Property(x => x.Location).IsVariableLength().HasMaxLength(80);
            Property(x => x.Name).IsVariableLength().HasMaxLength(80).IsRequired();
            Property(x => x.DateCreated);
            MapSingleType(a => new
            {
                a.Id,
                SiteId = a.Site.Id,
                ThumbnailId = a.Thumbnail.Id,
                a.Location,
                a.Name,
                a.DateCreated
            }).ToTable("Albums");
        }
    }

public class PhotoMap : EntityConfiguration<Photo>
    {
        public PhotoMap()
        {
            HasKey(x => x.Id);
            Property(x => x.Id).IsIdentity();
            Property(x => x.FileName).IsVariableLength().HasMaxLength(255).IsRequired();
            Property(x => x.Caption).IsVariableLength().HasMaxLength(255);
            Property(x => x.DateCreated);
            MapSingleType(a => new
            {
                a.Id,
                SiteAlbumId = a.Album.Id,
                a.FileName,
                a.Caption,
                a.DateCreated
            }).ToTable("AlbumPhotos");
        }
    }

Я что-то упустил или это выглядит правильно?Я ожидаю, что EF сгенерирует 1 к многим в моей базе данных, но он продолжает создавать справочную таблицу между альбомом и фотографиями (Album_Photos), но это не должно быть много ко многим.Любая помощь будет великолепна.

1 Ответ

6 голосов
/ 05 декабря 2010

По общему правилу, код EF сначала не создает таблицу ссылок в типичном сценарии «один ко многим», причина, по которой вы его получаете, заключается в том, что ваши ассоциации между объектами Album и Photo были приняты EF какявляясь своего рода ассоциацией многих ко многим:
Каждый альбом имеет коллекцию фотографий, а также каждая фотография имеет коллекцию альбомов, для которых эта фотография является миниатюрой (хотя соответствующее свойство навигации не указано явно в классе Photo и толькоАльбом имеет свойство Thumbnail).

Решение:

Начиная с EF CTP4, единственный способ исправить это - использовать Fluent API, но перед этим я немного изменю вашу модель идобавьте два явных FK в вашу модель, чтобы обеспечить максимальную гибкость при работе с вашими объектами.Они AlbumId на Photo и ThumbnailId на Album:

public class Photo {        
    public long Id { get; set; }
    public string Caption { get; set; }
    public string FileName { get; set; }
    public DateTime DateCreated { get; set; }

    public long AlbumId { get; set; }
    public virtual Album Album { get; set; }
}

public class Album {
    public long Id { get; set; }
    public string Name { get; set; }
    public string Location { get; set; }
    public DateTime DateCreated { get; set; }

    public long ThumbnailId { get; set; }
    public virtual Photo Thumbnail { get; set; }

    public virtual ICollection<Photo> Photos { get; set; }
}

public class PhotoMap : EntityConfiguration<Photo> {
    public PhotoMap() 
    {
        this.HasRequired(p => p.Album)
            .WithMany(a => a.Photos)
            .HasConstraint((p, a) => p.AlbumId == a.Id);

        Property(x => x.FileName).IsVariableLength().HasMaxLength(255)
                                                    .IsRequired();
        Property(x => x.Caption).IsVariableLength().HasMaxLength(255);
        MapSingleType(p => new {
            p.Id,
            SiteAlbumId = p.AlbumId,
            p.FileName,
            p.Caption,
            p.DateCreated
        })
        .ToTable("Photo");
    }
}

public class AlbumMap : EntityConfiguration<Album> {
    public AlbumMap()
    {
        this.HasRequired(a => a.Thumbnail)
            .WithMany()
            .WillCascadeOnDelete(false)
            .HasConstraint((a, p) => p.Id == a.ThumbnailId);

        Property(x => x.Location).IsVariableLength().HasMaxLength(80);
        Property(x => x.Name).IsVariableLength().HasMaxLength(80).IsRequired();
        MapSingleType(a => new {
            a.Id,
            a.ThumbnailId,
            a.Location,
            a.Name,
            a.DateCreated
        })
        .ToTable("Album");
    }
}


Это приводит к следующей желаемой схеме: alt text

...