C# EF代码第一个Fluent映射:0-1到多:HasOptional()with Many()

C# EF代码第一个Fluent映射:0-1到多:HasOptional()with Many(),c#,entity-framework,ef-code-first,foreign-keys,C#,Entity Framework,Ef Code First,Foreign Keys,我正在一个项目中使用EF,该项目中有一个我一直使用的现有数据库。我有两个表具有奇数映射(我相信是0-1到多)。部分问题是字段中可能存在垃圾,因此我希望完全可以从nav属性返回null 卡车零件可以选择性地与零件相关。 一个零件可以与0个或多个卡车零件相关(尽管我不需要在该方向上遍历该关系) 我的EF很接近,除了当我通过Include(“Part”)拉入关系时,它使用内部连接,我需要它使用左连接 课程: public class TruckPart { public int TruckPa

我正在一个项目中使用EF,该项目中有一个我一直使用的现有数据库。我有两个表具有奇数映射(我相信是0-1到多)。部分问题是字段中可能存在垃圾,因此我希望完全可以从nav属性返回null

卡车零件可以选择性地与零件相关。 一个零件可以与0个或多个卡车零件相关(尽管我不需要在该方向上遍历该关系)

我的EF很接近,除了当我通过Include(“Part”)拉入关系时,它使用内部连接,我需要它使用左连接

课程:

public class TruckPart
{
    public int TruckPartId { get; set; }
    public int PartId { get; set; }   
    public string Location { get; set; }
    public virtual Part Part { get; set; }
    // plus other fields
}

public class TruckPartMapping : EntityTypeConfiguration<TruckPart>
{
    public TruckPartMapping()
    {
        // Primary Key
       HasKey(t => t.TruckPartID);

       HasRequired(t => t.Part).WithMany().HasForeignKey(t => new { t.Location, t.PartID });
       //HasOptional(t => t.Part).WithMany().HasForeignKey(t => new { t.Location, t.PartID });
       //HasOptional(t => t.Part).WithMany().Map(t => t.MapKey("Location", "PartID"));
    }
}

public class Part
{
    public string Loc { get; set; }
    public int PartID { get; set; }
    // plus other fields
}

public class PartMapping : EntityTypeConfiguration<Part>
{
    public PartMapping()
    {
        // Primary Key
        HasKey(t => new { t.Loc, t.PartID});
    }
}
我尝试用Map(MapKey)替换HasForeignKey,但出现了错误(我假设是因为我已经有了这些属性):


我甚至可以在EF中添加这种nav属性吗?

为了使关系成为可选关系,您需要在
TruckPart
实体中添加一个可为空的外键属性(加上带有
HasOptional
的映射):


为了使关系成为可选关系,您需要在
TruckPart
实体中有一个可为空的外键属性(加上带有
HasOptional
的映射):


您是否打算在部件上启用延迟加载?公共虚拟部分{get;set;}是否已安装实体框架电动工具?通过这种方式,您可以在图表中查看上下文文件,并查看正在创建的联接类型。我正在使用SQL事件探查器并查看针对DBI运行的SQL。我建议为此使用EF power工具。如果我理解正确,您看到的错误是EF错误?我在最近的一个项目中遇到了类似的问题,这是一个救命稻草。如果您选择安装它们,您会遇到一个小问题,但很容易解决。然后您可以查看EF模式并查看正在生成的联接。您是否打算在部件上启用延迟加载?公共虚拟部分{get;set;}是否已安装实体框架电动工具?通过这种方式,您可以在图表中查看上下文文件,并查看正在创建的联接类型。我正在使用SQL事件探查器并查看针对DBI运行的SQL。我建议为此使用EF power工具。如果我理解正确,您看到的错误是EF错误?我在最近的一个项目中遇到了类似的问题,这是一个救命稻草。如果您选择安装它们,您会遇到一个小问题,但很容易解决。然后,您可以查看EF模式并查看正在生成的连接。如果我们假设DBA不允许我修改这个遗留数据库,这仍然有效吗?如果我把它设为int?它的值为42,但没有id为42的部件,EF会被弄糊涂吗?@AdamTegen:这取决于具体情况。如果加载包含
零件的
TruckPart
,它可能会工作,因为它现在是左连接。如果您尝试使用
PartId
null
保存
TruckPart
,它将不起作用,因为在数据库中,列不允许
null
。正如您所看到的,
int
has optional
的组合根本不起作用,而
int
has required
的组合会导致内部联接,这意味着甚至不会加载父级,这可能比使用
int?
has optional
的组合更糟糕。在任何情况下,EF始终假定数据库中存在强制约束。如果不是,则可能会出现意外行为。如果我们假设DBA不允许我修改这个遗留数据库,那么这仍然有效吗?如果我把它设为int?它的值为42,但没有id为42的部件,EF会被弄糊涂吗?@AdamTegen:这取决于具体情况。如果加载包含
零件的
TruckPart
,它可能会工作,因为它现在是左连接。如果您尝试使用
PartId
null
保存
TruckPart
,它将不起作用,因为在数据库中,列不允许
null
。正如您所看到的,
int
has optional
的组合根本不起作用,而
int
has required
的组合会导致内部联接,这意味着甚至不会加载父级,这可能比使用
int?
has optional
的组合更糟糕。在任何情况下,EF始终假定数据库中存在强制约束。如果不是,则可能出现意外行为。
System.Data.Entity.Edm.EdmAssociationType: 
    Multiplicity conflicts with the referential constraint in Role 
   'TruckPart_Part_Target' in relationship 'TruckPart_Part'. 
    Because all of the properties in the Dependent Role are non-nullable, 
    multiplicity of the Principal Role must be '1'.
 error 0019: Each property name in a type must be unique. 
             Property name 'Location' was already defined.
 error 0019: Each property name in a type must be unique. 
             Property name 'PartID' was already defined.
public int? PartId { get; set; }