【问题标题】:EntityFramework 1 to 0, 1 or many relationshipEntityFramework 1对0、1或多关系
【发布时间】:2017-09-22 21:49:58
【问题描述】:

我正在努力在实体框架中创建三个表之间的关系.. 我正在使用 C#、Sqlite 3.0 和 Entity Framework 6 开发 WPF 应用程序。

我有以下表格(类):

  1. 投资者
  2. 投资
  3. 图像存储

我想创建一个模型,以便 Investor 和 Investment(以及未来的其他类)可以存储 0、1 或 Many 图片。(从类名可以明显看出 Investor 只能有一个个人资料图片和 Investment 类可以有多个图像) 我的 ImageStore 类看起来像这样:

public class ImageStore : PropertyChangedNotification
    {
        [Key]
        public int ImageStoreId { get; set; }
        [Required]
        public string ImageFile { get; set; }
        [Required]
        public Byte[] ImageBlob { get; set; }

        public string FileName { get; set; }
        [Required]
        public int FileSize { get; set; }


        //public virtual ImageData ImageData { get; set; }
    }

为了创建 1 到 0,1 或 Many 关系,我创建了一个名为 ImageData 的中间表,如下所示(我不知道这是否真的是一个好方法,但这只是我能想到的现在..)

public class ImageData : PropertyChangedNotification
    {
        [Key]
        public int ImageDataId { get; set; }

        [ForeignKey("Investment")]
        public long? InvestmentId { get; set; }

        [ForeignKey("Investor")]
        public long? InvestorId { get; set; }

        [ForeignKey("ImageStore")]
        public int ImageStoreId { get; set; }

        public virtual ImageStore ImageStore { get; set; }

        public virtual Investment Investment { get; set; }

       public virtual Investor Investor { get; set; }
    }

我的投资者类如下所示:

public class Investor : PropertyChangedNotification
    {
        [Key]
        public long InvestorId { get; set; }        

        [NotMapped]
        [ForeignKey("ImageData")]
        public List<int> ImageDataList { get; set; }

        public virtual ICollection<ImageData> ImageDataCollection { get; set; }
        public virtual ICollection<Investment> Investments { get; set; }        
    }

我的投资类如下所示:

 public class Investment : PropertyChangedNotification
    {
        [Key]
        public long InvestmentId { get; set; }

       [ForeignKey("Investor")]
       [Required]
       public long FirstInvestorId { get; set; }       


        [NotMapped]
        [ForeignKey("ImageData")]
        public List<int> ImageDataList { get; set; }

        public virtual ICollection<ImageData> ImageDataCollection { get; set; }       

        public virtual Investor Investor { get; set; }

        [NotMapped]
        [Required (ErrorMessage = "First Investor is Required")]
        public Investor FirstInvestor { get; set; }
    }

这是我相关的fluent配置:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            // MyData Database does not pluralize table names
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

            modelBuilder.Entity<Investor>().HasOptional(s => s.ImageDataCollection);
            modelBuilder.Entity<Investment>().HasOptional(s => s.ImageDataCollection);
            //modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
        }

当我开始调试应用程序时,我收到以下错误:

  1. ImageData_Investment_Source::多重性在关系“ImageData_Investment”中的角色“ImageData_Investment_Source”中无效。因为从属角色属性不是关键属性,所以从属角色的多重性的上限必须是'*'
  2. ImageData_Investor_Source::多重性在关系“ImageData_Investor”中的角色“ImageData_Investor_Source”中无效。因为从属角色属性不是关键属性,所以从属角色的多重性的上限必须是'*'

有人可以建议我解决这个问题和/或实现我需要的最佳方法,我真的很感激。 谢谢

【问题讨论】:

  • 尝试将 FK 中的 int? 更改为 long?(或将 PK 中的 long 更改为 int
  • 在 Class 中进行更改后(O mad InvestoerId 和 InvestmentId 在 ImageData 类中太长了),我的第二个和第四个错误消失了,现在我离开了 Error#1 和 3
  • 有没有相关的fluent配置这里没有展示?
  • Ivan,我添加了相关的 fluent 配置,还更新了 ImageStore 类的两个属性的数据类型。
  • Ivan,您能否发表您的评论以删除 Fluent 行作为解决方案,因为我不希望您的努力被浪费,为我提供了很大的帮助。我会接受这个作为答案并打开一个新线程来讨论一个新问题。感谢您的帮助。

标签: c# wpf sqlite entity-framework-6


【解决方案1】:

流畅的配置

modelBuilder.Entity<Investor>().HasOptional(s => s.ImageDataCollection);
modelBuilder.Entity<Investment>().HasOptional(s => s.ImageDataCollection);

不完整。

由于您已经拥有必要的数据注释和导航/FK 属性,您可以简单地将其删除。或者,如果您想提供流畅的配置(我个人更喜欢,因为它允许您明确指定所有内容,而不依赖于约定和专门针对关系,而不是那么直观的 ForegnKeyInverseProperty 数据注释),那么您应该确保它准确地反映了相关实体中导航和 FK 属性的存在/不存在。

到目前为止,反映您的模型的正确流畅配置如下:

modelBuilder.Entity<Investor>()
    .HasMany(e => e.ImageDataCollection)
    .WithOptional(e => e.Investor)
    .HasForeignKey(e => e.InvestorId);

modelBuilder.Entity<Investment>()
    .HasMany(e => e.ImageDataCollection)
    .WithOptional(e => e.Investment)
    .HasForeignKey(e => e.InvestmentId);

【讨论】:

    猜你喜欢
    • 2017-10-05
    • 1970-01-01
    • 1970-01-01
    • 2012-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-28
    相关资源
    最近更新 更多