我有一个仅由其他实体的外键组成的实体。 我的简化类如下:
DeliverNote
Adress add1 {get; set;}
Adress add2 {get; set;}
我可以自己加载地址,但是我不能加载DeliveryNote,因为我默认情况下EF不会加载相关数据。 所以我看到了解决方案,主要是使用context.notes.Include(dn => dn.Adresses),但是我只是想不通如何告诉便笺或地址类如何彼此关联。基本上,当我键入“ dn”时。什么都没有显示。
我看到的最简单,可能可行的解决方案是来自Microsoft。在此页面https://docs.microsoft.com/de-de/ef/core/querying/related-data的github中,您可以看到Blog和Post类。在我看来,Post类似乎有缺陷,为什么Post必须知道它所在的Blog?在代码优先解决方案中,这也会使数据库混乱。如果同一篇文章要发布在多个博客上怎么办?
大多数解决方案似乎也都是某种形式的列表,我没有列表,只有简单的单个对象。我认为是1-1关系。
答案 0 :(得分:2)
如果您将模型定义为:
public class DeliverNote {
public int Id { get; set; }
public Adress addr1 { get; set; }
public Adress addr2 { get; set; }
}
public class Adress {
public int Id { get; set; }
}
然后您可以致电:
context.notes.Include(dn => dn.addr1).Include(dn => dn.addr2);
其中将包含相关数据。
您的模型没有为addr1或addr2定义外键,因此EF Core将为您创建阴影属性,即表中存在的列,但不作为c#模型中的属性。
答案 1 :(得分:1)
因此,您有一个数据库,该数据库具有一个function urlGenerator (key, value) {
let temp = '(?<='+`${key}`+'=)[^&]+'
let reg = new RegExp(temp,'g');
console.log(reg);
var url = "www.domain.com/?id=10&name=xxx&dob=2018-12-13";
// change the value for given key
return url.replace(reg, value);
}
result = urlGenerator('id', 15);
console.log(result);
result = urlGenerator('name', 'yyy');
console.log(result);
result = urlGenerator('dob', '2018-10-20');
console.log(result);
表和一个Addresses
表。每个DeliveryNotes
都有两个指向DeliveryNote
的外键:一个Addresses
和一个From
(您将其称为addr1和addr2)
如果您遵循entity framework code first conventions,将会看到以下内容:
To
在实体框架中,表的列由非虚拟属性表示。虚拟属性表示表之间的关系。
请注意,ICollection和FromAddress / ToAddress是虚拟的,因此不是列中的列。如果需要,您可以将其排除在课堂之外。但是,如果您具有这些虚拟属性,则不必自己进行(Group)Joins。
我可以自己加载地址,但是我不能加载DeliveryNote,因为默认情况下EF不会加载相关数据...我
由此很难检测到您想要哪种查询。
数据库查询的最慢部分之一是将所选数据从DBMS传输到本地进程。因此,将传输的数据减到最少是明智的。
如果使用class Address
{
public int Id {get; set;}
... // other properties
// every Address has sent zero or more delivery Notes (one-to-many)
public virtual ICollection<DeliveryNote> SentNotes {get; set};
// every Address has received zero or more delivery Notes (one-to-many)
public virtual ICollection<DeliveryNote> ReceivedNotes {get; set};
}
class DeliveryNote
{
public int Id {get; set;}
... // other properties
// every DeliveryNote comes from an Address, using foreign key
public int FromId {get; set;}
public virtual Address FromAddress {get; set;}
// every DeliverNote is sent to an Address, using foreign key:
public int ToId {get; set;}
public virtual Address ToAddress {get; set;}
}
,则将传输完整的对象,包括外键和不需要的所有属性。如果您有学校和学生的数据库,那么每个学生都将拥有他所就读学校的外键。如果您使用Include要求学校的ID为4的“有1000名学生的学校”,则您不想将外键SchoolId传送1000次,因为您已经知道它将具有值4
在实体框架中,仅当您要更改/更新获取的项目时才使用包括,否则使用选择
给出一堆DeliveryNotes,给我一些AddressDetails:
Include
实体框架知道一对多关系,并将为您执行适当的联接。
给出一些地址,给我一些收到的送达通知
IQueryable<DeliveryNote> deliveryNotes = dbContext.DeliveryNotes
.Where (deliveryNote => ...) // probably something with Id, or Date, or subject
.Select(deliveryNote => new
{
// select only the delivery note properties you actually plan to use
Subject = deliveryNote.Subject,
DeliveryDate = deliveryNote.DeliveryDate,
...
From = new
{
// select only the From properties you plan to use
Id = deliveryNote.FromAddress.Id,
Name = deliveryNote.FromAddress.Name,
Address = deliveryNote.FromAddress.Address,
...
}
To = new
{
// again: only properties you'll use
Name = deliveryNote.ToAddress.Name,
...
},
});
实体框架知道一对多关系,并将为您进行适当的组联接。
如果您具有一对多关系,并且想要“带有许多子项目的项目”,请从一侧开始使用虚拟ICollection。如果您想要带有其所属项目的子项目,请从多面开始,并在一侧使用虚拟属性