我正在mysql服务器上使用来自mysql的sakila示例数据库。图表如下所示。
重要的table是商店,库存和电影表。表之间的关系是多对多的,链接器表是inventory表。
我使用efcore2在一个新的dotnetcore项目中构建了这个数据库。我想弄一份商店的名单和他们的电影名单。
实体定义如下:
商店
public class Store
{
public Store()
{
Customer = new HashSet<Customer>();
Inventory = new HashSet<Inventory>();
Staff = new HashSet<Staff>();
}
public byte StoreId { get; set; }
public byte ManagerStaffId { get; set; }
public short AddressId { get; set; }
public DateTimeOffset LastUpdate { get; set; }
public Address Address { get; set; }
public Staff ManagerStaff { get; set; }
public ICollection<Customer> Customer { get; set; }
public ICollection<Inventory> Inventory { get; set; }
public ICollection<Staff> Staff { get; set; }
}
库存
public partial class Inventory
{
public Inventory()
{
Rental = new HashSet<Rental>();
}
public int InventoryId { get; set; }
public short FilmId { get; set; }
public byte StoreId { get; set; }
public DateTimeOffset LastUpdate { get; set; }
public Film Film { get; set; }
public Store Store { get; set; }
public ICollection<Rental> Rental { get; set; }
}
电影
public partial class Film
{
public Film()
{
FilmActor = new HashSet<FilmActor>();
FilmCategory = new HashSet<FilmCategory>();
Inventory = new HashSet<Inventory>();
}
public short FilmId { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public short? ReleaseYear { get; set; }
public byte LanguageId { get; set; }
public byte? OriginalLanguageId { get; set; }
public byte RentalDuration { get; set; }
public decimal RentalRate { get; set; }
public short? Length { get; set; }
public decimal ReplacementCost { get; set; }
public string Rating { get; set; }
public string SpecialFeatures { get; set; }
public DateTimeOffset LastUpdate { get; set; }
public Language Language { get; set;
public Language OriginalLanguage { get; set; }
public ICollection<FilmActor> FilmActor { get; set; }
public ICollection<FilmCategory> FilmCategory { get; set; }
public ICollection<Inventory> Inventory { get; set; }
}
我的背景如下:
modelBuilder.Entity<Inventory>(entity =>
{
entity.ToTable("inventory", "sakila");
entity.HasIndex(e => e.FilmId)
.HasName("idx_fk_film_id");
entity.HasIndex(e => new { e.StoreId, e.FilmId })
.HasName("idx_store_id_film_id");
最后,回购协议如下:
public IEnumerable<Store> GetStores()
{
return _context.Store.
Include(a => a.Inventory).
ToList();
}
问题:当我从控制器调用这个方法来获取我不知道的商店列表时´在postman上没有得到任何json响应。但是,如果我调试到从控制器返回的列表中,我会找到存储列表。问题是列表中包含:store->inventory->film->store->inventory->film->store。。。等等。创建一个循环依赖项来填充请求允许的进程内存。
可能的解决方案:我认为这与以下事实有关:在上下文中,两个外键都被定义为hasindex而不是haskey
entity.HasIndex(e => new { e.StoreId, e.FilmId })
.HasName("idx_store_id_film_id");
当我将其定义为haskey时,会得到一个错误:
'外键属性为{inventoryid':int}的'rental.inventory'与'inventory.rental'之间的关系不能以主键{storeid':byte,'filmid':short}为目标,因为它不兼容。为此关系配置一个主键或一组兼容的外键属性。'
1条答案
按热度按时间o3imoua41#
为了回答@hamzas的评论,我确实找到了解决这个问题的方法。我使用efcore通过scaffolding(db-first)构建实体和dbcontext。作为最佳实践,您应该使用模型(dto)来表示客户机的数据。efcore非常有助于我们灵活地访问这种m-to-n关系。这使我们能够灵活地以我们想要的方式向客户机表示这些数据。
不管你的用例是什么。必须将m到n的关系转换为1到n的模型。
用例1:您希望显示特定商店的所有电影。
解决方案
第1步:创建storedto(模型)
第二步:制作电影
第三步:使用自动Map器提供Map
第四步:正确地查询数据,不幸的是我没有´我们已经没有这个例子来测试这个代码了,所以这里是´我得试一下
在“include”部分,您只想获取storeid==inverntory.storeid的库存条目,然后从结果列表中包括films对象。我希望你能理解。你想打破你的m对n关系,让他们看起来像你的客户1对m。