繁体   English   中英

如何在 EF 中创建从两个表到一个源的一对一映射?

[英]How to create one-to-one mapping in EF from two tables to one source?

我想要 2 个模型,例如“人”和“动物”。 两者都在带有image_binary_id列的数据库(postrge)中建模。

    public class Person
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public ImageBinary ImageBinary { get; set; }
    }

    public class Animal
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public ImageBinary ImageBinary { get; set; }
    }

现在,我希望图像数据表使用 model 为两个对象“提供”图像:

    public class ImageBinary
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public byte[] Data { get; set; }
    }

在数据库中,我有外键连接“person.image_binary_id => image_binary.id”

如何在代码中定义映射,以便在 1 个事务中正确插入,如下所示:

var image = new ImageBinary(...);
var person = new Person() 
{
    ...,
    ImageBinary = image
}
PersonRepository.AddPerson(person);

我尝试像这样映射person ,但这会导致插入时 image_binary_id 为null

entity.HasOne(x => x.ImageBinary)
   .WithOne()
   .HasForeignKey("ImageBinary", "Id");

我知道如果“ImageBinary”表将包含person \ animal列,这可能会解决它,因为它会返回“导航”(将参数添加到WithOne() )-但我不想添加更多列(除非我必须。 ..)。

我考虑过添加联结表(person_id、image_binary_id),但这似乎很难维护,因为我还必须为所有未来的模型添加一个。

将 .NET 5 与 EF Core 版本 5 一起使用。

欢迎任何想法和解决方案。

这是您尝试执行的代码的第一个实现。

public class Person
    {
        [Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public long Id { get; set; }
        public string Name { get; set; }
        
        public long ImageBinRef { get; set; }
        [ForeignKey("ImageBinRef")]
        //or [ForeignKey(nameof(ImageBinRef))] I like this version better
        public ImageBinary ImageBinary { get; set; }
    }

这是我在这里所做的一些解释

  • key 属性告诉 Ef Id 是主键

  • DatabaseGenerated(DatabaseGeneratedOption.Identity) 告诉 ef 它是自动递增的

  • ForeignKey 属性将 fk 约束和索引添加到我在答案中为您定义的 ImageBinRef属性,因此您尝试运行的示例现在可以工作

另一件重要的事情是,您的 ImageBinary 类的主键是 long 类型,它不可为空,并且不接受 null 作为值。 这很重要,因为现在当您删除人员记录时,如果您不希望删除该记录,它也会删除与该记录相关的 ImageBinary 记录(我不知道这是否是您想要的),只需像这样声明属性

public long? ImageBinRef { get; set; } //Notice the question mark
    

问号表示它是一个可以为空的类型,所以现在当您删除人员记录时,它不会删除引用的图像记录..

请注意,字符串默认情况下可以为空,因此您无需担心:

说你有 COUNTRIES 表和 PERSON 表

public class PERSON{
   
 [Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
 public int PersonRowid {get;set:}
 public string PersonName {get;set:}

 public string PersonCountryCode {get;set;}

 [ForeignKey("PersonCountryCode")]
 public COUNTRIES Country {get;set;}
}

public class COUNTRIES{
   
 [Key]
 public string CountryCode {get;set:}
 public string CountryName {get;set:}
}

在此示例中,当您删除人员时,国家/地区记录仍将保留在表中,但是,如果您在删除人员记录时将 countrycode 的属性类型从 string 更改为 int,它也会从数据库中删除该国家/地区,这可能不是你想要的东西,为了防止这种情况,我们将我们的属性定义为可为空的..

抱歉,如果我犯了任何错字,我在添加代码示例时没有使用编译器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM