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



我想要两个模型,例如;"人";以及";动物";。二者都在具有CCD_ 1列的DB(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; }
}

现在,我希望图像数据表将";提供";两个对象的图像,使用模型:

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

在DB中,我有连接的外键";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列,这可能会解决问题,因为它将具有";导航";back(向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; }
}

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

  • 密钥属性告诉Ef Id是主密钥

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

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

这里的另一件重要的事情是,ImageBinary类的主键是不可为null的长类型,并且不接受null作为值。这一点很重要,因为现在当你删除一个人记录时,它也会删除与之相连的ImageBinary记录(我不知道这是否是你想要的(。如果你不想删除该记录,只需声明类似的属性

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

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

注意,字符串在默认情况下是可以为null的,因此您不需要担心以下问题:

假设您有Countrys表和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,它也将从数据库中删除该国家/地区,这可能不是您想要的,为了防止出现这种情况,我们将属性定义为null。。

对不起,如果我有错别字,我在添加代码示例时没有使用编译器。

编辑:

public class Animal
{
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
public string Name { get; set; }

public long ImageBinRef { get; set; }
[ForeignKey("ImageBinRef")]
public ImageBinary ImageBinary { get; set; }
}

最新更新