3

我处于这种情况,我有一个名为Elements的表。现在我创建一个名为Divergences的表,它将基本上存储Elements对。 Divergence的目的是检查两个Elements是否有分歧的答案。实体框架将两个表列映射到相同的相关表键

Element    Divergence 
---------    ---------- 
ElementId    ElementId1 
         ElementId2 

在上述表模式,ElementId1和​​是外键Elements表映射到ElementId和形成用于Divergence复合主键

我使用数据库第一种方法其中我在SQL Server Management Studio中创建表,之后我在实体框架设计器中执行Update Model from Database...

我面临的问题是,当EF设计师生成模型时,它会在Element类中创建2组ICollection<Element>,即ElementsElements1

enter image description here

这不会给我一个Divergences DbSet。

我想有什么是Divergence类,我会做这样的事情代码:

Divergence d = new Divergence(); 
d.Element1 = element1; 
d.Element2 = element2; 

Database.Divergences.Add(d); 
Database.SaveChanges(); 

,稍后:

Element e = Database.Elements.Single(e => e.ElementId == 7); 

var divergences = e.Divergences; 

我尝试添加一个新列到Divergence表如下:

Element    Divergence 
---------    ------------ 
ElementId    DivergenceId 
         ElementId1 
         ElementId2 

这正确地l在实体框架设计器中关联到1 <-> *关系。我终于得到了一个Divergences DbSet,但DivergenceId属性在代码中没用,我仍然在Element类中获得2组属性。需要注意的是,ElementId1和​​仍然构成复合主键。

您认为映射这种特定情况的正确方法是什么?感谢您的意见。

回答

2

而不是...

Divergence d = new Divergence(); 
d.Element1 = element1; 
d.Element2 = element2; 

Database.Divergences.Add(d); 
Database.SaveChanges(); 

...你可以实际使用:

element1.Elements = new List<Element>(); 
// if that collection isn't already instantiated, for example in the constructor 
element1.Elements.Add(element2); 

Database.SaveChanges(); 

这将创建一个完全相同的SQL语句INSERT到链接表,而不需要具有的Divergence实体。 (更改跟踪将认识到您通过向集合中添加项目并根据此更改推断出必需的SQL命令来更改关系。element1element2必须附加到状态Unchanged的上下文中,但这也是您的原始代码所需的为了正确工作。)

此外,而不是...

Element e = Database.Elements.Single(e => e.ElementId == 7); 
var divergences = e.Divergences; 

...你可以从Divergences表中提取列像这样:

var divergences = Database.Elements.Where(e => e.ElementId == 7) 
    .SelectMany(e1 => e1.Elements.Select(e2 => new 
    { 
     ElementId1 = e1.ElementId, 
     ElementId2 = e2.ElementId, 
    })) 
    .ToList(); 

所以,你会得到你想要的结果,而实体,并诚实地我会用这种方式。我没有意识到强制EF使用数据库优先方法创建该实体的方法,除非像您那样引入一些人造附加列。如果有一种方式,它可能是一种黑客或更难以实现和维护,而不仅仅是使用EF的默认值,即没有Divergence实体。

但是,您可以考虑删除其中一个集合(只需在模型表面中将其删除)。在我看来,这两种模式在这个模型中有点混乱。或者至少将它们重命名为SourceElementsTargetElements例如:)

+0

真棒Slauma!就是这样......我将以这种方式实现它,因为如你所说,没有内置的功能来映射我想要的方式。非常感谢您的关注! :) –

相关问题