Entity framework 6 code first - 添加引用另一个现有实体的实体
Entity framework 6 code first - Add entity with reference to another existing entity
假设我的数据库中有以下模型:
public class LetterEntity
{
public int Id {get; set;}
public string Content {get; set;}
public List<Destination> Destinations {get; set;}
public virtual Folder Folder {get; set;}
public int FolderId {get; set;}
}
现在我想在我的数据库中添加一封客户写的新信件:
public class SendLetterRequest
{
public string Content {get; set;}
public List<int> DestinationsIds {get; set;}
}
public void SaveLetterToDatabase(SendLetterRequest letter)
{
var letterEntity = new LetterEntity
{
Content = letter.Content;
FolderId = 1;
// How to insert the Destinations Ids in a way that I don't have to load all of those destinations to the context?
}
context.Set<LetterEntity>().Add(letterEntity);
context.SaveChanges();
}
我知道,如果 LetterEntity 只有一个 Destination 对象,我只需设置它的外键值,插入就可以了(就像我对 FolderId 所做的那样)。
使用实体列表时它是如何完成的 - 如何告诉 EF 这些 ID 已经在数据库中,而不是将它们全部提取到上下文中,以便它不会重新创建它们?
编辑:
我的 Destination 模型 -
public void Destination
{
// Manual key
public int Address {get; set;}
public string DestinationName {get; set;}
public string Information {get; set;}
}
好吧,您可能知道,有两种方法可以在 EF 中定义 many-to-many
复制关系。
(1) 隐式 link table
这是你用过的。您仅显式创建两个实体,通过导航 properties/and 或模型配置定义关系,并让 EF 维护所谓的 "link" table。这很容易,但缺点是您无法访问那个 table,因此添加相关项目的唯一方法是实际加载所需的实体并将它们添加到导航 属性 集合中。
(2) 显式 link table
在这里您明确定义 link 实体并配置 2 one-to-many
关系。这样您就可以访问并可以添加加载其他实体的相关记录 w/o。
例如,在您的情况下可能是这样的:
型号:
public class LetterEntity
{
public int Id { get; set; }
// ....
public List<LetterDestinationLink> Links { get; set; }
}
public class Destination
{
public int Id { get; set; }
// ....
public List<LetterDestinationLink> Links { get; set; }
}
public class LetterDestinationLink
{
[Key]
[Column(Order = 0)]
public int LetterId { get; set; }
[Key]
[Column(Order = 1)]
public int DestinationId { get; set; }
public LetterEntity Letter { get; set; }
public Destination Destination { get; set; }
}
上下文:
public class YourDbContext : DbContext
{
public DbSet<LetterEntity> LetterEntities { get; set; }
public DbSet<Destination> Destinations { get; set; }
public DbSet<LetterDestinationLink> LetterDestinationLinks { get; set; }
}
用例:
List<int> destinationIds = ...;
var letterEntity = new LetterEntity { ... };
letterEntity.Links = destinationIds.Select(destinationId =>
new LetterDestinationLink { Letter = letterEntity, DestinationId = destinationId })
.ToList();
context.Set<LetterEntity>().Add(letterEntity);
context.SaveChanges();
假设我的数据库中有以下模型:
public class LetterEntity
{
public int Id {get; set;}
public string Content {get; set;}
public List<Destination> Destinations {get; set;}
public virtual Folder Folder {get; set;}
public int FolderId {get; set;}
}
现在我想在我的数据库中添加一封客户写的新信件:
public class SendLetterRequest
{
public string Content {get; set;}
public List<int> DestinationsIds {get; set;}
}
public void SaveLetterToDatabase(SendLetterRequest letter)
{
var letterEntity = new LetterEntity
{
Content = letter.Content;
FolderId = 1;
// How to insert the Destinations Ids in a way that I don't have to load all of those destinations to the context?
}
context.Set<LetterEntity>().Add(letterEntity);
context.SaveChanges();
}
我知道,如果 LetterEntity 只有一个 Destination 对象,我只需设置它的外键值,插入就可以了(就像我对 FolderId 所做的那样)。 使用实体列表时它是如何完成的 - 如何告诉 EF 这些 ID 已经在数据库中,而不是将它们全部提取到上下文中,以便它不会重新创建它们?
编辑:
我的 Destination 模型 -
public void Destination
{
// Manual key
public int Address {get; set;}
public string DestinationName {get; set;}
public string Information {get; set;}
}
好吧,您可能知道,有两种方法可以在 EF 中定义 many-to-many
复制关系。
(1) 隐式 link table
这是你用过的。您仅显式创建两个实体,通过导航 properties/and 或模型配置定义关系,并让 EF 维护所谓的 "link" table。这很容易,但缺点是您无法访问那个 table,因此添加相关项目的唯一方法是实际加载所需的实体并将它们添加到导航 属性 集合中。
(2) 显式 link table
在这里您明确定义 link 实体并配置 2 one-to-many
关系。这样您就可以访问并可以添加加载其他实体的相关记录 w/o。
例如,在您的情况下可能是这样的:
型号:
public class LetterEntity
{
public int Id { get; set; }
// ....
public List<LetterDestinationLink> Links { get; set; }
}
public class Destination
{
public int Id { get; set; }
// ....
public List<LetterDestinationLink> Links { get; set; }
}
public class LetterDestinationLink
{
[Key]
[Column(Order = 0)]
public int LetterId { get; set; }
[Key]
[Column(Order = 1)]
public int DestinationId { get; set; }
public LetterEntity Letter { get; set; }
public Destination Destination { get; set; }
}
上下文:
public class YourDbContext : DbContext
{
public DbSet<LetterEntity> LetterEntities { get; set; }
public DbSet<Destination> Destinations { get; set; }
public DbSet<LetterDestinationLink> LetterDestinationLinks { get; set; }
}
用例:
List<int> destinationIds = ...;
var letterEntity = new LetterEntity { ... };
letterEntity.Links = destinationIds.Select(destinationId =>
new LetterDestinationLink { Letter = letterEntity, DestinationId = destinationId })
.ToList();
context.Set<LetterEntity>().Add(letterEntity);
context.SaveChanges();