'FromSql'操作的结果中没有所需的列,并且[NotMapped]没有帮助

我正在使用EF Core 3.0将数据从SQL Server存储过程提取到名为Recipient的对象模型中。 Recipient模型具有定义的两个属性EnvelopeIdName,这些属性未从存储过程中返回。当我使用FromSqlInterpolated调用存储过程时,收到错误消息

  

'FromSql'操作的结果中没有所需的列'EnvelopeId1'

根据我在EF Core文档中所读的内容,我应该能够向这些属性添加[NotMapped]属性,并且EF Core在读取或写入数据库时​​应该能够忽略它们,对吗?不幸的是,这对我不起作用,并且出现了以上错误。

如果我在存储过程中添加了两列,并在对象模型中删除了[NotMapped]属性,则一切正常。这证明我的其他列/属性名称正确匹配,并且在任何地方都没有错字。

我已经看到使用DbQuery而不是DbSet的建议,但是已经过时了,所以我不想使用它。我已经看到了使用两种不同对象模型的建议,一种具有与存储过程结果集完全匹配的属性,但这只会导致很多额外的模型。我在这里做什么错了?

我的对象模型:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MyNamespace.Models
{
    public class Recipient
    {
        [Key]
        public long RecipientId { get; set; }
        [NotMapped]
        public Guid? EnvelopeId { get; set; }
        public string Type { get; set; }
        public string UserId { get; set; }
        public string Email { get; set; }
        [NotMapped]
        public string Name { get; set; }
        public string RoleName { get; set; }
        public int RoutingOrder { get; set; }
        public string Status { get; set; }
        public DateTime StatusDate { get; set; }

        public Recipient() { }
    }
}

我的数据库上下文:

using microsoft.EntityFrameworkCore;
using MyNamespace.Models;

namespace MyNamespace.Data
{
    public class MyDbContext : DbContext
    {
        public virtual DbSet<Recipient> Recipient { get; set; }
        public virtual DbSet<Envelope> Envelope { get; set; }
        public virtual DbSet<Template> Template { get; set; }

        public MyDbContext (DbContextOptions<MyDbContext> options) : base(options)   
        { }
    }
}

我的失败代码:

FormattableString sql = $"EXEC dbo.MyStoredProcedure @Param1={param1},@Param2={param2}";
var result = await MyDbContext.Recipient.FromSqlInterpolated(sql).ToListAsync();

编辑#1 ...

Envelope对象模型:

public class Envelope
{
    [Key]
    public Guid EnvelopeId { get; set; }
    public string Status { get; set; }
    public DateTime StatusDate { get; set; }
    public DateTime StatusPollDate { get; set; }
    [NotMapped]
    public List<Recipient> Recipients { get; set; }

    public Envelope() {
        Recipients = new List<Recipient>();
        StatusPollDate = DateTime.Parse("1753-01-01");
    }
}

存储过程结果集架构:

[RecipientId] bigint,[Type] varchar(20),[UserId] varchar(50),[Email] varchar(100),[RoleName] varchar(100),[RoutingOrder] int,[Status] varchar(13),[StatusDate] datetime

在阅读了一些答案和评论后,我意识到EF正在创建shadow属性,因为它认识到RecipientEnvelope对象的子级。坦白地说,我真的应该在结果集中添加EnvelopeId(并删除[NotMapped])以安抚EF Core。我没有在存储过程的结果集中返回EnvelopeId的唯一原因是因为我已经将它作为输入参数进行了传递,并且认为这浪费了网络资源来传递某些东西然后得到并返回到每个结果集记录。

现在我不知道EnvelopeId1的来源,但这就是错误消息所提及的内容。如您在我的对象模型和存储过程结果集模式中所看到的,我只引用过EnvelopeId。我最好的猜测是,当EF Core决定创建shadow属性时,由于我已经在对象模型中拥有它,所以它无法使用EnvelopeId,因此它创建了一个名为EnvelopeId1的对象,然后期望它可以出现在存储过程的结果集中。

weedssjl 回答:'FromSql'操作的结果中没有所需的列,并且[NotMapped]没有帮助

此错误消息有两个原因:

  

'FromSql'操作的结果中没有所需的列'EnvelopeId1'

显而易见的是,对于SQL结果集中的每一列,在对象图中都必须有一个您想要合并的对应属性,在这种情况下,您的Recipient类没有{{1} }。

由于查询是存储过程,因此将SQL结果发布到此类问题中是明智的,因为它将显示您试图映射到对象图的SQL结构。

EnvelopeId1在您的SQL表中但不在您的对象图中的原因是因为实体框架为Shadow Property创建了foreign that you have not defined a property

您尚未列出EnvelopeId1的架构,但是我的钱表明您拥有等效的Envelope属性。

ICollection<Recipient>创建一个NotMapped属性只会使该模式更加混乱,相反,我们应该正确地对其进行映射,或者应该从存储过程输出中将其忽略。

  

如果要在EF(.Net或Core)中使用EnvelopeId变体,则应始终在架构类中将导航属性定义为 Shadow Auto 数据库中的外键列会引起麻烦,除非您明确省略数据库中存在但架构中不存在的列

     
    

这意味着您无需FromSql即可明确定义所有列。

  

解决方案1:修改存储过程
您可以简单地修改存储过程,以不从收件人表中返回SELECT *

解决方案2:为数据类中所有关系的两端完全定义属性
这里我使用EvelopeId1作为名称,因此不需要迁移,但是我建议您将其更改为EnvelopeId1,我个人使用数据库中以数字结尾的任何字段的存在为这表明我的一些人际关系定义不充分。

EnvelopeId

这是基于您的Envelope类具有与该部分定义相似的定义的假设:

public class Recipient
{
    [Key]
    public long RecipientId { get; set; }
    public Guid? EnvelopeId1 { get; set; }
    [ForeignKey(nameof(EnvelopeId1))]
    public virtual Envelope Envelope { get; set; }
    public string Type { get; set; }
    public string UserId { get; set; }
    public string Email { get; set; }
    [NotMapped]
    public string Name { get; set; }
    public string RoleName { get; set; }
    public int RoutingOrder { get; set; }
    public string Status { get; set; }
    public DateTime StatusDate { get; set; }

    public Recipient() { }
}
本文链接:https://www.f2er.com/3163580.html

大家都在问