【问题标题】:Domain Modeling and Mapping with EF CPT5使用 EF CPT5 进行域建模和映射
【发布时间】:2010-12-08 04:35:59
【问题描述】:

我正在尝试建立一个包含照片集的相册。每个相册都会有一组照片和一张拇指照片。这就是我所拥有的,但 EF 似乎不喜欢它。我正在使用 EF CPT5

模型

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 long ThumbnailId { 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<br/>{ get { return _dateCreated; } set { _dateCreated = value; } }
  public long AlbymId { get; set; }
  public virtual Album Album { get; set; }
 }

映射代码:

public class AlbumMap : EntityTypeConfiguration<Album> {
  public AlbumMap() {
    HasRequired(x => x.Thumbnail).WithMany().HasForeignKey(a => a.ThumbnailId).WillCascadeOnDelete(false);
        Property(x => x.Location).IsVariableLength().HasMaxLength(80);
        Property(x => x.Name).IsVariableLength().HasMaxLength(80).IsRequired();
    }
 }

 public class PhotoMap : EntityTypeConfiguration<Photo> {
  public PhotoMap() {
    HasRequired(p => p.Album).WithMany(a => a.Photos).HasForeignKey(p => p.AlbymId);
    Property(x => x.FileName).IsVariableLength().HasMaxLength(255).IsRequired();
    Property(x => x.Caption).IsVariableLength().HasMaxLength(255);
    Property(x => x.DateCreated);
    ToTable("SiteAlbumPhotos");
    }
 }

上下文

public class Database : ObjectContext {

        public Database(EntityConnection connection) : base(connection) {
            ContextOptions.LazyLoadingEnabled = true;
            ContextOptions.ProxyCreationEnabled = true;
        }

        private IObjectSet<User> _users;
        private IObjectSet<Site> _sites;
        private IObjectSet<SiteDonation> _donations;
        private IObjectSet<SiteAnnouncement> _siteAnnouncements;
        private IObjectSet<SiteData> _siteData;
        private IObjectSet<SiteLink> _siteLinks;
        private IObjectSet<SitePost> _sitePosts;
        private IObjectSet<Theme> _theme;
        private IObjectSet<Album> _siteAlbums;
        private IObjectSet<Photo> _siteAlbumPhotos;
        private IObjectSet<CommunityPost> _communityPosts;
        private IObjectSet<CommunityComment> _communityComments;

        public IObjectSet<User> Users {
            get{ return _users ?? (_users = ObjectSet<User>()); }
        }
        public IObjectSet<Album> SiteAlbums {
            get { return _siteAlbums ?? (_siteAlbums =  ObjectSet<Album>()); }
        }
        public IObjectSet<Photo> SiteAlbumsPhotos {
            get { return _siteAlbumPhotos ?? (_siteAlbumPhotos = ObjectSet<Photo>()); }
        }
        public IObjectSet<Site> Sites {
            get{ return _sites ?? (_sites = ObjectSet<Site>()); }
        }

        public IObjectSet<SiteDonation> SiteDonations {
            get { return _donations ?? (_donations = ObjectSet<SiteDonation>()); }
        }

        public IObjectSet<SiteAnnouncement> SiteAnnouncements {
            get { return _siteAnnouncements ?? (_siteAnnouncements = ObjectSet<SiteAnnouncement>()); }
        }

        public IObjectSet<SiteData> SiteData {
            get { return _siteData ?? (_siteData = ObjectSet<SiteData>()); }
        }

        public IObjectSet<SiteLink> SiteLinks {
            get { return _siteLinks ?? (_siteLinks = ObjectSet<SiteLink>()); }
        }

        public IObjectSet<SitePost> SitePosts {
            get { return _sitePosts ?? (_sitePosts = ObjectSet<SitePost>()); }
        }

        public IObjectSet<Theme> Themes { 
            get { return _theme ?? (_theme = ObjectSet<Theme>()); }
        }
        public IObjectSet<CommunityPost> CommunityPosts {
            get { return _communityPosts ?? (_communityPosts = ObjectSet<CommunityPost>()); }
        }
        public IObjectSet<CommunityComment> CommunityComments {
            get { return _communityComments ?? (_communityComments = ObjectSet<CommunityComment>()); }
        }

        public virtual IObjectSet<T> ObjectSet<T>() where T : class, IEntity {
            return CreateObjectSet<T>();
        }
        public virtual void Commit() {
            SaveChanges();
        }
    }

数据库工厂

public class DatabaseFactory : Disposable, IDatabaseFactory
    {
        private static readonly ModelBuilder builder = CreateBuilder();
        private readonly DbProviderFactory _providerFactory;
        private readonly string _connectionString;
        private Database _database;
        //
        public DatabaseFactory(DbProviderFactory providerFactory, string connectionString)
        {
            Check.Argument.IsNotNull(providerFactory, "providerFactory");
            Check.Argument.IsNotNullOrEmpty(connectionString, "connectionString");
            _providerFactory = providerFactory;
            _connectionString = connectionString;
        }
        //
        public Database Get()
        {
            if(_database == null)
            {
                var connection = _providerFactory.CreateConnection();
                connection.ConnectionString = _connectionString;
                //_database = builder.CreateModel(connection); LEG 1 CPT 3
                //var ctx = dbModel.CreateObjectContext<ObjectContext>(_connectionString); LEG 1 CPT 3
                //var modelBuilder = builder.CreateModel(); LEG 2 CPT 4
                //_database = modelBuilder.CreateObjectContext<Database>(connection); LEG 2 CPT 4
                //_database = modelBuilder.CreateObjectContext<Database>(connection); LEG 2 CPT 4
                var modelBuilder = builder.Build(connection);
                var dbModel = new DbModel(modelBuilder);
                _database = dbModel.CreateObjectContext<Database>(connection);

            }

            return _database;
        }
        //
        protected override void DisposeCore()
        {
            if (_database != null)
            {
                _database.Dispose();
            }
        }
        //
        private static ModelBuilder CreateBuilder()
        {
            //ContextBuilder<Database> contextBuilder = new ContextBuilder<Database>();
            var contextBuilder = new ModelBuilder();
            //IEnumerable<Type> configurationTypes = typeof(DatabaseFactory)
            //    .Assembly
            //    .GetTypes()
            //    .Where(type => type.IsPublic && type.IsClass && !type.IsAbstract && !type.IsGenericType && typeof(StructuralTypeConfiguration).IsAssignableFrom(type) && (type.GetConstructor(Type.EmptyTypes) != null));

            //foreach (StructuralTypeConfiguration configuration in configurationTypes.Select(type => (StructuralTypeConfiguration)Activator.CreateInstance(type)))
            //{
            //    contextBuilder.Configurations.Add(configuration);
            //}
            contextBuilder.Configurations.Add(new CommunityCommentMap());
            contextBuilder.Configurations.Add(new CommunityPostMap());
            contextBuilder.Configurations.Add(new SiteAlbumMap());
            contextBuilder.Configurations.Add(new SiteAlbumPhotoMap());
            contextBuilder.Configurations.Add(new SiteAnnouncementMap());
            contextBuilder.Configurations.Add(new SiteDataMap());
            contextBuilder.Configurations.Add(new SiteDonationMap());
            contextBuilder.Configurations.Add(new SiteLinkMap());
            contextBuilder.Configurations.Add(new SiteMap());
            contextBuilder.Configurations.Add(new SitePostMap());
            contextBuilder.Configurations.Add(new ThemeMap());
            contextBuilder.Configurations.Add(new UserMap());
            return contextBuilder;
        }
    }

我是否正确建模和映射?我需要能够在不指定缩略图的情况下创建新专辑。截至目前,一切正常,直到我尝试添加缩略图,然后我收到此错误:

System.Data.UpdateException:无法确定相关操作的有效排序。由于外键约束、模型要求或存储生成的值,可能存在依赖关系。

在 System.Data.Mapping.Update.Internal.UpdateTranslator.DependencyOrderingError(IEnumerable`1 余数) 在 System.Data.Mapping.Update.Internal.UpdateTranslator.ProduceCommands() 在 System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager,IEntityAdapter 适配器) 在 System.Data.Objects.ObjectContext.SaveChanges(SaveOptions 选项) 在 Database.cs 中的 PostHope.Infrastructure.DataAccess.Database.Commit():第 74 行 在 BuildDatabase.cs 中的 PostHope.Infrastructure.DataAccess.IntegrationTests.BuildDatabase.Add_test_data_to_database():第 252 行

任何帮助都会很棒!

【问题讨论】:

    标签: entity-framework-4 ef-code-first


    【解决方案1】:

    我们通过 EF CTP4 here 解决了这个问题。现在这里是 EF CTP5 的更新,今天早些时候是 released

    public class Photo 
    {
        public long PhotoId { get; set; }        
        [MaxLength(255)]
        public string Caption { get; set; }        
        [MaxLength(255)][Required]
        public string FileName { get; set; }        
        public DateTime DateCreated { get; set; }
        public long AlbumId { get; set; }        
        public virtual Album Album { get; set; }
    }
    
    [Table("SiteAlbumPhotos")]
    public class Album 
    {
        public long AlbumId { get; set; }        
        [MaxLength(80)][Required]
        public string Name { get; set; }        
        [MaxLength(80)]
        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 : EntityTypeConfiguration<Photo> {
        public PhotoMap() {            
            HasRequired(p => p.Album).WithMany(a => a.Photos)
                                     .HasForeignKey(p => p.AlbumId);
        }
    }
    
    public class AlbumMap : EntityTypeConfiguration<Album> {
        public AlbumMap() {
            HasRequired(a => a.Thumbnail).WithMany()
                                         .HasForeignKey(a => a.ThumbnailId)
                                         .WillCascadeOnDelete(false);
        }
    }
    
    public class MyContext : DbContext {
        public DbSet<Photo> Photos { get; set; }
        public DbSet<Album> Albums { get; set; }
    
        protected override void OnModelCreating(ModelBuilder modelBuilder) {
            modelBuilder.Configurations.Add<Photo>(new PhotoMap());
            modelBuilder.Configurations.Add<Album>(new AlbumMap());
        }
    }
    

    此数据库架构的结果:

    【讨论】:

    • 再次感谢!当我尝试创建数据库时出现此错误: System.Data.UpdateException: Unable to determine a valid ordering fordependent operations。由于外键约束、模型要求或存储生成的值,可能存在依赖关系。有什么想法吗??
    • 您是完全复制并粘贴了我的模型,还是根据我的帖子更改了您的模型?您在我的答案中看到的 DB Schema 是针对 CTP5 运行此模型的结果,因此它经过 100% 的测试和工作。如果您使用任何自定义代码,请发布它,以便我可以看到那里发生了什么。谢谢。
    • 我在我的上下文中使用 IObjectSet 和 ObjectContext。我还没有重建我的上下文和我的存储库来使用 DbContext 和 DbSet 因为我将不得不重新编写一堆测试并且使用编译查询是不同的。我也在使用流利的 API 而不是数据注释。我认为有很多代码要发布,如果您愿意,我可以让您访问 SVN 存储库。再次感谢。
    • 好的,我添加了我的contex和DatabaseFactory。让我知道我需要改变什么,或者我是否更好地使用 DbContex 和 DbSet 重建我的上下文。
    • 使用 Fluent API 很好,我特意将您的一些 Fluent API 映射转换为数据注释,以向您展示一些新的 CTP5 功能以及您如何不再需要使用 Fluent API。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-21
    • 1970-01-01
    • 1970-01-01
    • 2013-02-14
    • 1970-01-01
    • 1970-01-01
    • 2016-04-01
    相关资源
    最近更新 更多