Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 加载嵌套实体_C#_Asp.net Core_Entity Framework Core_Ef Fluent Api_Owned Types - Fatal编程技术网

C# 加载嵌套实体

C# 加载嵌套实体,c#,asp.net-core,entity-framework-core,ef-fluent-api,owned-types,C#,Asp.net Core,Entity Framework Core,Ef Fluent Api,Owned Types,我有一个关于嵌套实体和实体框架核心中一些奇怪行为的问题 我应该从数据库表加载实体会议。会议有多个属性,但只有位置会给我带来麻烦。位置存储a-位置;-)会议简化如下。 位置更简单,它包含名称、描述、GPSCoordinates和地址。见下文 Address保存一个地址,尽管该类有更多属性,但下面对其进行了简化 从Db检索会议时,一切都很好。除非出现名称、描述和GPSCoordinates都为null的罕见情况,否则无论存储在Address中的任何值如何,Location都为null 如果我将Nam

我有一个关于嵌套实体和实体框架核心中一些奇怪行为的问题

我应该从数据库表加载实体会议。会议有多个属性,但只有位置会给我带来麻烦。位置存储a-位置;-)会议简化如下。 位置更简单,它包含名称、描述、GPSCoordinates和地址。见下文 Address保存一个地址,尽管该类有更多属性,但下面对其进行了简化

从Db检索会议时,一切都很好。除非出现名称、描述和GPSCoordinates都为null的罕见情况,否则无论存储在Address中的任何值如何,Location都为null

如果我将Name从Null更改为空字符串“”,则没有问题,所有内容都会按预期加载

会议、地点和地址的所有值都存储在平坦的数据库表中。该表是使用Fluent Api配置的。另一个类课程继承了Meeting并存储在同一个表中-因此是decriminator-但它应该没有影响

为了简单起见,下面的代码被简化了

public class Meeting : BaseEntity<long>
{
    public string Name { get; set; }
    public Location Location { get; set; }
}

public class Location
{
    public string Name { get; set; }
    public string Description { get; set; }
    public PostalAddress Address { get; set; }
    public Point GpsCoordinates { get; set; }
}

public class PostalAddress
{
    public string StreetAddress1 { get; set; }
    public string ZipCode { get; set; }
    public string City { get; set; }
    public string Country { get; set; }
}

Meeting meet = context.meetDbSet.Include(p=>p.Location).ThenInclude(p=>p.Address).FirstOrDefault();


public void Configure(EntityTypeBuilder<Meeting> builder)
{
    builder
        .ToTable("Meetings")
        .HasKey(p => p.Id);

    builder
        .HasDiscriminator<string>("Meeting_Descriminator")
        .HasValue<Meeting>("")
        .HasValue<Course>("Course");

    builder
        .OwnsOne(p => p.Location, location =>
            {
                location
                    .Property(p => p.Name)
                    .HasColumnType("nvarchar(max)")
                    .IsRequired(false);

                location
                    .Property(p => p.Description)
                    .HasColumnType("nvarchar(max)")
                    .IsRequired(false);

                location
                    .OwnsOne(p => p.Address, postaladdress =>
                        {
                            postaladdress
                                .Property(p => p.StreetAddress1)
                                .HasColumnName("StreetAddress1")
                                .HasColumnType("nvarchar(max)")
                                .IsRequired(false);
                            postaladdress
                                .Property(p => p.ZipCode)
                                .HasColumnType("nvarchar(max)")
                                .IsRequired(false);
                            postaladdress
                                .Property(p => p.City)
                                .HasColumnName("City")
                                .HasColumnType("nvarchar(max)")
                                .IsRequired(false);
                            postaladdress
                                .Property(p => p.Country)
                                .HasColumnName("Country")
                                .HasColumnType("nvarchar(max)")
                                .IsRequired(false);
                        });

                    location
                        .Property(p => p.GpsCoordinates)
                        .HasColumnType("geography")
                        .IsRequired(false);
            });
}
公共类会议:BaseEntity
{
公共字符串名称{get;set;}
公共位置位置{get;set;}
}
公共类位置
{
公共字符串名称{get;set;}
公共字符串说明{get;set;}
公共邮政地址{get;set;}
公共点GpsCoordinates{get;set;}
}
公务舱邮品
{
公共字符串StreetAddress1{get;set;}
公共字符串ZipCode{get;set;}
公共字符串City{get;set;}
公共字符串国家{get;set;}
}
Meeting meet=context.meetDbSet.Include(p=>p.Location)。然后Include(p=>p.Address)。FirstOrDefault();
公共void配置(EntityTypeBuilder)
{
建设者
.ToTable(“会议”)
.HasKey(p=>p.Id);
建设者
.HasDiscriminator(“会议描述者”)
.HasValue(“”)
.HasValue(“课程”);
建设者
.OwnsOne(p=>p.Location,Location=>
{
位置
.Property(p=>p.Name)
.HasColumnType(“nvarchar(最大)”)
.i被要求(虚假);
位置
.Property(p=>p.Description)
.HasColumnType(“nvarchar(最大)”)
.i被要求(虚假);
位置
.OwnsOne(p=>p.地址,邮资=>
{
邮资
.Property(p=>p.StreetAddress1)
.HasColumnName(“StreetAddress1”)
.HasColumnType(“nvarchar(最大)”)
.i被要求(虚假);
邮资
.Property(p=>p.ZipCode)
.HasColumnType(“nvarchar(最大)”)
.i被要求(虚假);
邮资
.Property(p=>p.City)
.HasColumnName(“城市”)
.HasColumnType(“nvarchar(最大)”)
.i被要求(虚假);
邮资
.Property(p=>p.Country)
.姓名(“国家”)
.HasColumnType(“nvarchar(最大)”)
.i被要求(虚假);
});
位置
.Property(p=>p.GpsCoordinates)
.HasColumnType(“地理”)
.i被要求(虚假);
});
}

我认为这可能是因为您使用的是自有类型。对于拥有的类型,类型的键定义为其属性的组合。当所有属性都为null时,无法定义键,因此也不会加载地址。但当使用自有类型时,这种行为听起来是合乎逻辑的。当某事物被拥有时,如果父属性不存在,则假定该事物不存在。如果不是这样,你应该改变结构。

我终于找到了解决方案。事实证明,这在EF Core中是一个问题,但在location上添加导航属性并使该属性成为必需的属性就成功了

请注意,它必须在自己拥有的类型之后进行配置

public void Configure(EntityTypeBuilder<Meeting> builder)
{

builder
    .ToTable("Meetings")
    .HasKey(p => p.Id);

builder
    .HasDiscriminator<string>("Meeting_Descriminator")
    .HasValue<Meeting>("")
    .HasValue<Course>("Course");

builder
    .OwnsOne(p => p.Location, location =>
        {
            location
                .Property(p => p.Name)
                .HasColumnType("nvarchar(max)")
                .IsRequired(false);

            location
                .Property(p => p.Description)
                .HasColumnType("nvarchar(max)")
                .IsRequired(false);

            location
                .OwnsOne(p => p.Address, postaladdress =>
                    {
                        postaladdress
                            .Property(p => p.StreetAddress1)
                            .HasColumnName("StreetAddress1")
                            .HasColumnType("nvarchar(max)")
                            .IsRequired(false);
                        postaladdress
                            .Property(p => p.ZipCode)
                            .HasColumnType("nvarchar(max)")
                            .IsRequired(false);
                        postaladdress
                            .Property(p => p.City)
                            .HasColumnName("City")
                            .HasColumnType("nvarchar(max)")
                            .IsRequired(false);
                        postaladdress
                            .Property(p => p.Country)
                            .HasColumnName("Country")
                            .HasColumnType("nvarchar(max)")
                            .IsRequired(false);
                    });

                location
                    .Property(p => p.GpsCoordinates)
                    .HasColumnType("geography")
                    .IsRequired(false);
        });
builder
    .Navigation(p => p.Location)
    .IsRequired(true);
}
public void配置(EntityTypeBuilder)
{
建设者
.ToTable(“会议”)
.HasKey(p=>p.Id);
建设者
.HasDiscriminator(“会议描述者”)
.HasValue(“”)
.HasValue(“课程”);
建设者
.OwnsOne(p=>p.Location,Location=>
{
位置
.Property(p=>p.Name)
.HasColumnType(“nvarchar(最大)”)
.i被要求(虚假);
位置
.Property(p=>p.Description)
.HasColumnType(“nvarchar(最大)”)
.i被要求(虚假);
位置
.OwnsOne(p=>p.地址,邮资=>
{
邮资
.Property(p=>p.StreetAddress1)
.HasColumnName(“StreetAddress1”)
.HasColumnType(“nvarchar(最大)”)
.i被要求(虚假);
邮资
.Property(p=>p.ZipCode)
.HasColumnType(“nvarchar(最大)”)
.i被要求(虚假);
邮资
.Property(p=>p.City)
.HasColumnName(“城市”)
.HasColumnType(“nvarchar(最大)”)
.i被要求(虚假);
邮资
.Property(p=>p.Country)
哈斯科先生