我是Entity Framework的新手,我花了最后一个 4小时天试图让(看似简单的)简单的工作关系。
我有三个班:人,房子,车库
到目前为止,我已经阅读了10篇不同的文档,这些文档对我来说只会让人感到困惑。我尝试使用注释解决它,但似乎我也必须使用这种流畅的api东西。
我得到的最远的是将房屋和车库与一个人相关联,但不是彼此相关。现在我不得不定义一个关系的原则结束,我甚至不理解它应该做什么。
现在我得到了
无法确定相关操作的有效排序。由于外键约束,模型要求或存储生成的值,可能存在依赖关系。
试图解决一系列不同的错误。
通过编写我自己的查询,我一直在PHP中手动实现这些关系。这是我第一次在一个更大的框架中进行数据库工作,这应该会让事情变得更容易,但到目前为止,我已经在从DatabaseReader填充对象方面取得了更大的成功。
从我的逻辑角度来看,三个类/表之间的关系应该非常简单,但我找不到类似关系的例子,或者让它只是工作。
所以我的问题是:
我准备了一个演示项目:https://github.com/Zaphox/DatabaseTest
它包含三个类,上下文和应该成功完成(但没有)的关系测试。
感谢您提供解决此问题的所有帮助和提示!
Ž。
在尝试了所有建议之后,我注意到任何循环关系都会导致EF中的错误,而且似乎无法创建这样的引用,甚至0..1到0..1自引用似乎不起作用。< / p> 然而,我已经实施了一个至少让我工作的黑客,但它太可怕了,我希望有人告诉我有更好的方法。
db.Buildings.OfType<House>().Where(h => h.Garage.Id == myGarage.Id).First()
)我还考虑在Garage中添加一个NotMapped House字段,它自己查找房子,但它会干扰其他查询,所以这也不是一个有效的选项。
最让我烦恼的是,有很多关于自我引用和喜欢的文章,但仅限于1到n关系。任何尝试使1到1或0..1到0..1的关系总是失败,EF无法弄清楚“顺序”。
事情是EF认为必须在House表中放置GarageId FK,在Garage表中放置HouseId FK,这是无稽之谈。我只需要在House表中使用GarageId,它可以用作向后引用。我可以实现此代码,但它与EF查询不兼容,并且通常会干扰其他正在运行的查询,因为您无法一次运行两个查询。
GitHub上的演示项目使用当前版本进行更新,有点可行,但每次我想找到属于车库的房子时都需要进行大量额外的查询。
答案 0 :(得分:2)
显然问题是House
和Garage
之间的关系。
我只需要在House表中使用GarageId,它可以用作向后引用。
实际上,当您在Garage
类上放置仅 House
导航属性时,默认情况会发生这种情况(唯一的区别是FK列名称为{{1 }})。这称为单向关联。通过这样的设置,EF认为Garage_Id
是从属的,House
是主体,两者都是可选的。重要的是FK列是在依赖表中创建的。
所以这就是您目前在测试项目中所具有的功能。通过将Garage
属性添加到House
类来使关联双向化时会出现问题:
Garage
在这种情况下,EF没有足够的信息您的意图是什么,因此您需要提供该信息。请记住,您需要public class House
{
public int Id { get; set; }
public Garage Garage { get; set; }
public string Style { get; set; }
}
public class Garage
{
public int Id { get; set; }
public House House { get; set; }
public int Size { get; set; }
}
表中的GarageId
FK,所以这里是您需要添加的相应Fluent配置(House
部分是可选的 - 如果您跳过它,FK列将会像你当前的项目一样被称为Map
:
Garage_Id
一切都会按预期工作。
答案 1 :(得分:1)
实体框架不喜欢没有明确主体的关系。在这种情况下,任何一个实体都可以不存在另一个实体,也不依赖于另一个实体。
我建议您重新设计模型,以便有一个Building
和House
来自的Garage
抽象类。然后,您可以将Person
与Building
相关联,并在具体类型“住宅”和Garage
中找到关联的Building
链接。
示例:
public abstract class Building
{
public Person Person { Get; Set; }
public Building Building { Get; Set; }
}
public class House : Building
{
// Other House properties
}
public class Garage : Building
{
// Other Garage properties
}
然后,在业务逻辑中,您可以强制关联的建筑物与this.GetType() != Building.GetType()