Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.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#_Entity Framework Core - Fatal编程技术网

C# 实体框架核心代码首先尝试将存储过程添加为表

C# 实体框架核心代码首先尝试将存储过程添加为表,c#,entity-framework-core,C#,Entity Framework Core,您好,我有一个名为dbo.GetFolderDocumentsHierarchy的存储过程,它直接映射到下面的类 public class DocumentDto:IModel { public int FolderId { get; set; } [CanBeNull] public int Id { get; set; } public string FolderName { get; set; } public string DocumentName

您好,我有一个名为dbo.GetFolderDocumentsHierarchy的存储过程,它直接映射到下面的类

public class DocumentDto:IModel
{
    public int FolderId { get; set; }
    [CanBeNull]
    public int Id { get; set; }
    public string FolderName { get; set; }
    public string DocumentName { get; set; }
    public string ParentName { get; set; }
    public int? ParentId { get; set; }
}
我已经像这样把它添加到我的上下文中

builder.Query<DocumentDto>();
builder.Query();
我可以补充一点,我称之为:

var dtos = await _context
                .Set<DocumentDto>()
                .FromSqlRaw("EXEC dbo.GetFolderDocumentsHierarchy @Skip, @Take, @UserId", sqlParameters)
                .ToListAsync();
var dtos=wait\u上下文
.Set()
.FromSqlRaw(“EXEC dbo.GetFolderDocumentsHierarchy@Skip、@Take、@UserId”、sqlParameters)
.ToListAsync();
现在讨论我的问题,每次创建新迁移时,都会将以下代码添加到迁移和快照中

            migrationBuilder.CreateTable(
            name: "DocumentDto",
            columns: table => new
            {
                FolderId = table.Column<int>(nullable: false),
                Id = table.Column<int>(nullable: false),
                FolderName = table.Column<string>(nullable: true),
                DocumentName = table.Column<string>(nullable: true),
                ParentName = table.Column<string>(nullable: true),
                ParentId = table.Column<int>(nullable: true)
            },
            constraints: table =>
            {
            });
migrationBuilder.CreateTable(
名称:“DocumentDto”,
列:表=>new
{
FolderId=table.Column(可空:false),
Id=table.Column(可空:false),
FolderName=table.Column(可空:true),
DocumentName=表.列(可空:true),
ParentName=table.Column(可空:true),
ParentId=table.Column(可空:true)
},
约束:表=>
{
});
在快照中:

            modelBuilder.Entity("Models.Dtos.DocumentDto", b =>
            {
                b.Property<string>("DocumentName")
                    .HasColumnType("nvarchar(max)");

                b.Property<int>("FolderId")
                    .HasColumnType("int");

                b.Property<string>("FolderName")
                    .HasColumnType("nvarchar(max)");

                b.Property<int>("Id")
                    .HasColumnType("int");

                b.Property<int?>("ParentId")
                    .HasColumnType("int");

                b.Property<string>("ParentName")
                    .HasColumnType("nvarchar(max)");

                b.ToTable("DocumentDto");
            });
modelBuilder.Entity(“Models.Dtos.DocumentDto”,b=>
{
b、 财产(“文件名”)
.HasColumnType(“nvarchar(max)”);
b、 财产(“FolderId”)
.HasColumnType(“int”);
b、 属性(“FolderName”)
.HasColumnType(“nvarchar(max)”);
b、 财产(“Id”)
.HasColumnType(“int”);
b、 属性(“父ID”)
.HasColumnType(“int”);
b、 财产(“父名”)
.HasColumnType(“nvarchar(max)”);
b、 ToTable(“DocumentDto”);
});
我如何才能使其不再添加到迁移中

编辑: 添加完整上下文

    public virtual DbSet<ApplicationUser> ApplicationUsers { get; set; }
    public virtual DbSet<Appointment> Appointments { get; set; }
    public virtual DbSet<Campaign> Campaigns { get; set; }
    public virtual DbSet<Contact> Contacts { get; set; }
    public virtual DbSet<Customer> Customers { get; set; }
    public virtual DbSet<Deal> Deals { get; set; }
    public virtual DbSet<Document> Documents { get; set; }
    public virtual DbSet<Folder> Folders { get; set; }
    public virtual DbSet<Group> Groups { get; set; }
    public virtual DbSet<GroupDocument> GroupDocuments { get; set; }
    public virtual DbSet<UserDocument> UserDocuments { get; set; }
    public virtual DbSet<UserGroup> UserGroups { get; set; }
    public virtual DbSet<UserFolder> UserFolders { get; set; }
    public virtual DbSet<UserTask> UserTasks { get; set; }
    public virtual DbSet<Opportunity> Opportunities { get; set; }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        builder.Entity<UserTask>()
            .HasIndex(x => x.OwnerId);

        builder.Entity<Group>()
            .HasMany(x => x.Campaigns)
            .WithOne(x => x.Group);
公共虚拟数据库集应用程序用户{get;set;}
公共虚拟数据库集约会{get;set;}
公共虚拟数据库集活动{get;set;}
公共虚拟数据库集联系人{get;set;}
公共虚拟数据库集客户{get;set;}
公共虚拟数据库集事务{get;set;}
公共虚拟数据库集文档{get;set;}
公共虚拟数据库集文件夹{get;set;}
公共虚拟数据库集组{get;set;}
公共虚拟数据库集GroupDocuments{get;set;}
公共虚拟数据库集用户文档{get;set;}
公共虚拟数据库集用户组{get;set;}
公共虚拟数据库集用户文件夹{get;set;}
公共虚拟数据库集用户任务{get;set;}
公共虚拟数据库集机会{get;set;}
模型创建时受保护的覆盖无效(ModelBuilder)
{
基于模型创建(生成器);
builder.Entity()
.HasIndex(x=>x.OwnerId);
builder.Entity()
.HasMany(x=>x.campaims)
.一组(x=>x组);
#pragma警告禁用618 builder.Query(); #pragma警告恢复618

        builder.Entity<GroupDocument>()
            .HasKey(gd => new { gd.GroupId, gd.DocumentId });
        builder.Entity<UserDocument>()
            .HasKey(x => new {x.UserId, x.DocumentId});
        builder.Entity<UserFolder>()
            .HasKey(x => new {x.UserId, x.FolderId});

    }
builder.Entity()
.HasKey(gd=>new{gd.GroupId,gd.DocumentId});
builder.Entity()
.HasKey(x=>new{x.UserId,x.DocumentId});
builder.Entity()
.HasKey(x=>new{x.UserId,x.FolderId});
}

您应该能够在模型创建时忽略
中的类,如下所示:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Ignore<DocumentDto>();
}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
Ignore();
}

Ivan Stoev的回答中提到了主要技巧,那就是始终添加一个
到view
映射语句。即使没有风景。唯一的区别是EF core 5不支持
。要查看(null)
,您必须输入一些字符串

一般来说,您的选择是:

1

modelBuilder.Entity
(eb=>
{
eb.HasNoKey();
eb.ToSqlQuery(“EXEC StoredProcedureWithoutParameters”);
//或者:eb.ToSqlQuery(“选择…从…”);
eb.ToView(“虚拟视图名称”);//防止创建表。
}
);
或者,当存在将DTO映射到的视图时:

2

modelBuilder.Entity
(eb=>
{
eb.HasNoKey();
eb.ToView(“MyView”);//映射到现有视图
}
);
或者,仅将DTO映射为无键实体:

3

modelBuilder.Entity
(eb=>
{
eb.HasNoKey();
eb.ToView(“虚拟视图名称”);//防止创建表
}
);
使用选项3时,应使用已有的代码填充DTO,如:

context.Set()
.FromSqlRaw(“EXEC dbo.GetFolderDocumentsHierarchy@Skip、@Take、@UserId”,
sqlParameters)
据我所知,这是使用带参数的存储过程的唯一方法。也许有一些奇特的方法可以使用选项1,让EF将
Where
语句的谓词传递给原始SQL查询,但我对此表示怀疑


我认为最好的选择是将DTO映射到真实视图(选项2,正如您在评论中提到的,您现在可以这样做),因为在这种情况下,
IQueryable
可以通过
Where
语句进行过滤。此外,它还可以以生成一条SQL语句的方式进行组合,这允许数据库引擎查询优化器计算整个查询计划。当然,这只有在存储过程代码可以转换为视图的情况下才可能实现。

除非您在上下文中声明了
DbSet
属性,否则不应创建表。我同意。但确实如此,如果有帮助,我会发布我的完整上下文。建议您至少升级到EF core 3。在这种情况下,将是一个重复。在EF 5中,您不能使用
null
作为
ToView
的参数。我使用的是EF Core 3.1.8,那么您可以将此过时的m