Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.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# 当对象的导航属性为空时,EF不抓取对象_C#_Linq_Entity Framework Core - Fatal编程技术网

C# 当对象的导航属性为空时,EF不抓取对象

C# 当对象的导航属性为空时,EF不抓取对象,c#,linq,entity-framework-core,C#,Linq,Entity Framework Core,我的问题是-如果数据库中的导航属性为“null”,我的查询将不会返回我要查询的主对象 为清楚起见,我的问题不是.Include()中的导航属性返回null。我的问题是,该财产预计为空,当它为空时,市场不会被退回 这里有一个例子来说明我的意思: 我的代码: markets = await _context.Markets .Include(x => x.Agency) .Include(x => x

我的问题是-如果数据库中的导航属性为“null”,我的查询将不会返回我要查询的主对象

为清楚起见,我的问题不是.Include()中的导航属性返回null。我的问题是,该财产预计为空,当它为空时,市场不会被退回

这里有一个例子来说明我的意思:

我的代码:

            markets = await _context.Markets
                .Include(x => x.Agency)
                .Include(x => x.Location)?.ThenInclude(x => x.State)?
                .Include(x => x.Location).ThenInclude(x => x.Country)
                .Where(x => x.Deleted == false
                && x.Agency.Deleted == false).ToListAsync();
我有一些市场,它们有一个导航属性
位置
,而这个位置又有一个导航属性
状态
。对于某些
位置
状态
为空。在
位置
模型中定义的
状态
外键为
长?

但是,由于某些原因,结果列表中没有返回“my Markets with null States”,返回的实体中包含了.Include()语句中包含的所有这些字段,并且不为null

在我的include之后,我最初的代码没有
。。。比如:

.Include(x=>x.Location)。然后Include(x=>x.State)
这样做不起作用。我添加了nullable,认为它可能会有所帮助,尽管它没有

这里有人有什么建议吗?运行此语句时,我得到以下异常:
.SqlNullValueException:数据为空。无法对空值调用此方法或属性。
但是,异常不会中断流,并且返回的对象没有null
状态

任何和所有的提示将不胜感激

编辑:

需要注意的是,当我的所有导航属性都不为null时,代码工作得非常好。只有当State为null(唯一可为null的导航属性)时,才会出现此问题

型号:

public class Market
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public long MarketId { get; set; }
        
        [ForeignKey("Location")]
        public long HeadquartersId { get; set; }
        
        [Required]
        public virtual Location Location { get; set; }
}

public class Location
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public long LocationId { get; set; }
        
        [ForeignKey("State")]
        public long? StateId { get; set; }

        [ForeignKey("Country")]
        public long CountryId { get; set; }

        [Required]
        public virtual State State { get; set; }

        [Required]
        public virtual Country Country { get; set; }
    }

最终,问题是我的位置模型中我的状态导航属性上的[Required]注释

不幸的是,这是Entity Framework和Blazor使用相同数据注释之间冲突的众多示例之一

在我的示例中,状态是必需的,因为在Blazor中表单验证需要它。然而,在我的数据库中,StateId实际上是一个可为空的外键,因为后端不一定需要它

我提出了两种解决方法,如果您知道更好的解决方案,请随意添加其他解决方法

  • 为Blazor创建单独的前端模型,为EF创建单独的后端模型。我知道,丑陋的重复代码。然而,这可以将关注点分开,避免“此处需要,但此处不需要”类型的问题

  • 在我的情况下,我也可以有一个单独的查询,首先检查我的国家。如果Country是一个特定的值,我就不会.Include(x=>x.State)。这是更具体的,但对于一些类似的情况可能是必要的,因为已经有一个不能改变太多的代码库


  • 这有点冗长,但是看看是否可以在DBContext的
    OnModelCreating
    中手动配置关系

    例如:

    模型创建时受保护的覆盖无效(ModelBuilder)
    {
    builder.Entity(a=>
    {
    a、 HasOne(e=>e.Location).WithMany().HasForeignKey(e=>e.HeadquartersId).IsRequired(false);
    });
    builder.Entity(a=>
    {
    a、 HasOne(e=>e.State).WithMany().HasForeignKey(e=>e.StateId).IsRequired(false);
    a、 HasOne(e=>e.Country).WithMany().HasForeignKey(e=>e.CountryId).IsRequired(false);
    });
    }
    
    您是否尝试过此
    .Include(“Location”).Include(“Location.State”)
    ?@sowmyadhargouri这是一个有趣的想法,我尝试了一下,但不幸的是它没有成功:(你能展示模型和它们的配置吗?@ESG当然,我刚刚在原始帖子的编辑中包含了我的模型-希望它能说明这里的问题。所需的可能是一个问题,因为框架可能认为这些关系不是可选的。你试过在模型创建时将它们设置为可选的吗在DbContext中?只是好奇……您是否有一个好的源代码来解释.HasOne.WithMany…和其他Fluent选项。这个解决方案实际上不起作用,但是删除我的位置导航属性上的[Required](而不是将ForeignKey设置为.IsRequired(false))确实起作用。不过,在我的情况下,我不得不保留它[必选],所以我不得不在下面的回答中解决问题。无论如何,你真的应该将DTO和视图模型分开。它们是两个完全不同的域。这就是为什么像Automapper这样的LIB存在于两者之间进行转换。