[英]Entity Framework 6 - primary key on navigation property
使用Code First方法和Entity Framework 6.1.3
,我正在嘗試根據這篇文章創建和配置我自己的多對多表。 我非常同意他的看法:我不想遵守這些慣例,因為這限制了我的設計。
看看Code First中的多對多有效載荷類:
public class FooBar
{
[Key, Column(Order = 1)]
public virtual Foo Foo { get; set; }
[Key, Column(Order = 2)]
public virtual Bar Bar { get; set; }
//some more 'payload' properties
}
我想保持這種方式而不添加標量屬性。 所以,我不希望在我的模型這些屬性:
public int FooId { get; set; }
public int BarId { get; set; }
我的問題是明確是否有可能在實體框架6有一個導航屬性這樣的(復合)鍵? 此問題的大多數答案都是基於早期版本的Entity Framework,因此無法實現。 所以問題是,現在可能嗎?
在這個答案中,它提到:
您需要以特定方式設置類,以便EF識別您嘗試實現的目標。
但是,如果它在技術上可行,我仍然不清楚。 如果是,有人可以在代碼中提供如何實現這一目標的示例嗎?
你不能這樣做 。
不僅使用EF 6.X,而且EF Core也不可能。 這是設計的。 如果您不在聯結表上定義這些標量屬性,EF不知道如何映射關系。 我不得不說,這是設計的。 不幸的是,你在這里沒有任何其他選擇。 您必須在聯結表上包含這些標量屬性。
我希望這對某些人有用。
經過幾個小時的搜索引擎搜索,我終於在這里做到了。 可悲的是,你和我所面臨的同樣問題都沒有答案。 我只是不想撤回我的設計選擇並創建許多標量類型,就像你在帖子中所說的那樣。
我想出了實現基本OOP的解決方案:
// let's assume we would like to have each ObjectModel with
// unique Name and Class properties
// this two data will identify the whole row. (i.e ShadowHawk:Bow)
class ObjectModel {
public string Name { get; set; }
public ItemClass ItemClass { get; set; }
...
public MagicAttr[] Attributes { get; set; }
...
}
class ObjectEntity : ObjectModel {
public int Class_id
...
other foreign keys as primary keys
}
使用這種方法,我的ObjectModel仍然是干凈的,獨立於EntityFramework地獄。 我使用Fluent API進行配置,(也可以使用Data anno。原來的ObjectModel仍然很干凈)
在您的上下文中使用ObjectEntity,即DbSet<ObjectEntity>
您可能會遇到需要向下轉換方法(從父級轉換為子級)的問題。 這就是我在父類上實現向下轉換的方法(使用AutoMapper)
using AutoMapper;
...
public ObjectEntity Downcast() {
var config = new MapperConfiguration(cfg => cfg.CreateMap<ObjectModel, ObjectEntity>());
var mapper = config.CreateMapper();
return mapper.Map<ObjectEntity>(this);
}
想通知你以及:
直接來自MSDN:
https://msdn.microsoft.com/en-us/library/jj591620(v=vs.113).aspx#Anchor_7
如果您選擇不在CLR類型上定義外鍵,但想要指定它在數據庫中應具有的名稱,請執行以下操作:
modelBuilder.Entity<Course>()
.HasRequired(c => c.Department)
.WithMany(t => t.Courses)
.Map(m => m.MapKey("ChangedDepartmentID"));
在努力解決同樣的問題並在網上進行大量研究后,我最終也在這里,最后我放棄了這個想法。 然而,在我的項目的另一部分工作后,我發現這可能實際上是可能的(至少它現在按預期工作)。 但是,在這個例子中使用EF Core。
以刪除關鍵注釋的OP類為例
public class FooBar
{
public virtual Foo Foo { get; set; }
public virtual Bar Bar { get; set; }
//some more 'payload' properties
}
假設Foo和Bar實體類具有如下導航屬性
public class Foo
{
...
public virtual ICollection<FooBar> FooBars { get; set; }
}
public class Bar
{
...
public virtual ICollection<FooBar> FooBars { get; set; }
}
我為FooBar創建了這個配置類
public class FooBarConfiguration : IEntityTypeConfiguration<FooBar>
{
public void Configure(EntityTypeBuilder<FooBar> builder)
{
var fkFoo = "FooId";
var fkBar = "BarId";
builder.HasKey(fkFoo, fkBar);
builder
.HasOne(fb => fb.Foo)
.WithMany(f => f.FooBars)
.HasForeignKey(fkFoo);
builder
.HasOne(fb => fb.Bar)
.WithMany(b => b.FooBars)
.HasForeignKey(fkBar);
}
}
並在DbContext類OnModelCreating覆蓋中應用了配置
protected override void OnModelCreating(ModelBuilder builder)
{
....
builder.ApplyConfiguration(new FooBarConfiguration());
}
如上所述,這似乎表現得如預期。 希望它可以幫助其他人搜索同樣的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.