是否有人知道如何在EF Core中查询DB以获得多对多关系,但更像是从一侧留下外部联接?
让我解释一下我的意思。
Currency.cs
public class Currency
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid UID { get; set; } = Guid.NewGuid();
public string ISOCode { get; set; }
public string Symbol { get; set; }
[JsonIgnore]
public List<RegionCurrency> RegionCurrencies { get; set; }
}
RegionCurrency.cs
public class RegionCurrency
{
public Guid CurrencyUID { get; set; }
public Guid RegionUID { get; set; }
[ForeignKey("CurrencyUID")]
public Currency Currency { get; set; }
[ForeignKey("RegionUID")]
public Region Region { get; set; }
}
Region.cs
public class Region
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid UID { get; set; } = Guid.NewGuid();
[StringLength(8)]
public string CountryISOCode { get; set; }
public List<RegionCurrency> RegionCurrencies { get; set; }
}
MyContext.cs
public class LookupTablesContext : DbContext
{
public virtual DbSet<Currency> Currecies { get; set; }
public virtual DbSet<RegionCurrency> RegionCurrency { get; set; }
public virtual DbSet<Region> Regions { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.HasDefaultSchema(SchemaName);
modelBuilder.Entity<RegionCurrency>()
.HasKey(t => new { t.CurrencyUID, t.RegionUID })
.HasName("PK_RegionCurrency");
modelBuilder.Entity<RegionCurrency>()
.HasOne(pt => pt.Region)
.WithMany(p => p.RegionCurrencies)
.HasForeignKey(pt => pt.RegionUID);
modelBuilder.Entity<RegionCurrency>()
.HasOne(pt => pt.Currency)
.WithMany(p => p.RegionCurrencies)
.HasForeignKey(pt => pt.CurrencyUID);
modelBuilder.Entity<Currency>()
.HasIndex(c => c.ISOCode)
.HasName("UX_Currency_ISOCode")
.IsUnique();
modelBuilder.Entity<Region>()
.HasIndex(c => c.CountryISOCode)
.HasName("UX_Region_CountryISOCode")
.IsUnique();
}
}
我的查询:
var result = ctx.Currencies
.Include(c => c.RegionCurrencies)
.ThenInclude(rc => rc.Select(rcs => rcs.Regions)) // This seems to be wrong
.SingleOrDefault(c => c.ISOCode == "EUR");
我也尝试使用包含,如下图所示:
请注意,RegionCurrencies表可以包含0-N关系,我想获得Currency实体,即使RegionCurrency表中没有记录。
这个(和类似的尝试)最终出现在这样的异常中:
类型&#39; System.ArgumentException&#39;的例外情况发生在Microsoft.EntityFrameworkCore.dll中但未在用户代码中处理
附加信息:属性表达式&#39; rc =&gt; {来自RegionCurrency rc in rcs select [pts] .Regions}&#39;无效。表达式应代表属性访问权限:&#39; t =&gt; t.MyProperty&#39 ;.有关包含相关数据的更多信息,请参阅http://go.microsoft.com/fwlink/?LinkID=746393。
Dependencies:
"Microsoft.EntityFrameworkCore": "1.0.1",
"Microsoft.EntityFrameworkCore.SqlServer": "1.0.1",
我找不到任何有效的例子。但当然我只是失明。
感谢您的帮助。
答案 0 :(得分:2)
您可以按照以下所示进行操作。
var tag = ctx.Tags.Include(t => t.PostTags)
.ThenInclude(p => p.Post).FirstOrDefault(d => d.TagId == "2");
var posts = tag.PostTags.Select(c => c.Post).ToList();
注意:有时VS没有正确显示智能感知。所以要注意intellisense:D。一种解决方案可能是:关闭VS并启动它的新实例。
例如: intellisense对此.Include(t => t.PostTags)
工作正常。但要注意这个.ThenInclude(p => p.Post)
。你必须不依赖它而写智能感知。希望微软能够在VS的未来版本中解决这个问题。
结果:
tag
的价值:
值posts
:
测试数据:
更新:
它正在工作。请看代码。
var currency = db.Currecies.Include(t => t.RegionCurrencies)
.ThenInclude(p => p.Region)
.FirstOrDefault(t => t.UID == Guid.Parse("0f8fad5b-d9cb-469f-a165-70867728950e"));
var regions = currency.RegionCurrencies.Select(c => c.Region).ToList();
结果:
currency
的价值:
值regions
:
Git Repo: EfCoreManyToMany