C# 具有自定义返回类型的实体框架核心-无法为';BookInfo&x27;因为上下文的模型中不包括此类型
具有自定义返回类型的实体框架核心 我正在尝试使用EF Core 3.1从Sql Server查询自定义返回类型。有两个实体Book和Author,我想获取BookInfo,其中包含BookId、BookName和AuthorName。以下是代码 存储过程:C# 具有自定义返回类型的实体框架核心-无法为';BookInfo&x27;因为上下文的模型中不包括此类型,c#,sql-server,.net-core,entity-framework-core,C#,Sql Server,.net Core,Entity Framework Core,具有自定义返回类型的实体框架核心 我正在尝试使用EF Core 3.1从Sql Server查询自定义返回类型。有两个实体Book和Author,我想获取BookInfo,其中包含BookId、BookName和AuthorName。以下是代码 存储过程: CREATE PROC GetBookInfos AS SELECT Books.BookId, Books.Name AS BookName, Authors.FirstName+' '+Authors.LastName AS Author
CREATE PROC GetBookInfos
AS
SELECT Books.BookId, Books.Name AS BookName, Authors.FirstName+' '+Authors.LastName AS AuthorName
FROM Books
INNER JOIN Authors
ON Books.AuthorId = Authors.AuthorId;
Book.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace EFCoreShop
{
public class Book
{
public long BookId { get; set; }
public string Name { get; set; }
public double Price { get; set; }
public long AuthorId { get; set; }
public Author Author { get; set; }
}
}
Author.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace EFCoreShop
{
public class Author
{
public long AuthorId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public List<Book> Books { get; set; }
}
}
ShopContext.cs
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Text;
namespace EFCoreShop
{
class ShopContext:DbContext
{
public DbSet<Author> Authors { get; set; }
public DbSet<Book> Books { get; set; }
public DbSet<BookInfo> BookInfos { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Data Source=**********;Database=EFCoreShop;User ID=*********;Password=***********");
}
}
}
更新:下面的代码将在不使用存储过程的情况下解决此问题。但是,我们希望使用存储过程得到结果。不过,如果您不想使用存储过程,也可以这样做 Program.cs(无存储过程,不是我想要的)
使用Microsoft.EntityFrameworkCore;
使用制度;
使用System.Collections.Generic;
使用System.Linq;
名称空间EFCoreShop
{
班级计划
{
静态void Main(字符串[]参数)
{
使用(ShopContext ShopContext=new ShopContext())
{
//IEnumerable bookInfos=shopContext.bookInfos.FromSqlRaw(“exec GetBookInfos”).ToList();
//foreach(bookInfos中的var bookInfo)
//{
//Console.WriteLine($“图书Id:{bookInfo.BookId}图书名称:{bookInfo.BookName}作者名称:{bookInfo.AuthorName}”);
//}
//这比存储过程更易于管理
IEnumerable books=shopContext.books.Include(book=>book.Author.ToList();
foreach(账簿中的var账簿)
{
Console.WriteLine($“图书Id:{Book.BookId}图书名称:{Book.Name}作者名称:{Book.Author.FirstName+''+图书.Author.LastName}”);
}
}
}
}
}
您应该在BookInfo中使用“DbQuery”而不是“DbSet”
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Text;
namespace EFCoreShop
{
class ShopContext:DbContext
{
public DbSet<Author> Authors { get; set; }
public DbSet<Book> Books { get; set; }
public DbQuery<BookInfo> BookInfos { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Data Source=**********;Database=EFCoreShop;User ID=*********;Password=***********");
}
}
}
使用Microsoft.EntityFrameworkCore;
使用制度;
使用System.Collections.Generic;
使用系统文本;
名称空间EFCoreShop
{
类ShopContext:DbContext
{
公共数据库集作者{get;set;}
公共数据库集书籍{get;set;}
公共DbQuery BookInfos{get;set;}
配置时受保护的覆盖无效(DBContextOptions Builder Options Builder)
{
optionsBuilder.UseSqlServer(“数据源=******;数据库=EFCoreShop;用户ID=*********;密码=**********”;
}
}
}
您应该在BookInfo中使用“DbQuery”而不是“DbSet”
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Text;
namespace EFCoreShop
{
class ShopContext:DbContext
{
public DbSet<Author> Authors { get; set; }
public DbSet<Book> Books { get; set; }
public DbQuery<BookInfo> BookInfos { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Data Source=**********;Database=EFCoreShop;User ID=*********;Password=***********");
}
}
}
使用Microsoft.EntityFrameworkCore;
使用制度;
使用System.Collections.Generic;
使用系统文本;
名称空间EFCoreShop
{
类ShopContext:DbContext
{
公共数据库集作者{get;set;}
公共数据库集书籍{get;set;}
公共DbQuery BookInfos{get;set;}
配置时受保护的覆盖无效(DBContextOptions Builder Options Builder)
{
optionsBuilder.UseSqlServer(“数据源=******;数据库=EFCoreShop;用户ID=*********;密码=**********”;
}
}
}
出于兴趣,为什么要使用proc通过导航属性获取已经存在的内容?似乎有些过分?我只想得到我想要的列,不需要额外的列。这纯粹是为了使用Linq从数据库中压缩所需的数据,我正在提取我目前不需要的额外列。可以使用一个新类作为视图模型并使用。选择,但我想我看到了好处:)出于兴趣,为什么要使用proc通过导航属性获取已经存在的内容?似乎有些过分?我只想得到我想要的列,不需要额外的列。这纯粹是为了使用Linq从数据库中压缩所需的数据,我正在提取目前不需要的额外列。可以使用新类作为视图模型并使用。选择,但我想我看到了好处:)未处理的异常。System.InvalidOperationException:无法为“BookInfo”创建数据库集,因为上下文的模型中不包含此类型。我在我的项目中遇到了这个错误。自定义类型仍未实现。此外,VS2019建议我使用DbSet而不是DbQuery.Unhandled异常。System.InvalidOperationException:无法为“BookInfo”创建数据库集,因为上下文的模型中不包含此类型。我在我的项目中遇到了这个错误。自定义类型仍未实现。此外,VS2019建议我使用DbSet而不是DbQuery。
Unhandled exception. System.InvalidOperationException: Cannot create a DbSet for 'BookInfo' because this type is not included in the model for the context.
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.get_EntityType()
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.CheckState()
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.get_EntityQueryable()
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.System.Linq.IQueryable.get_Provider()
at Microsoft.EntityFrameworkCore.RelationalQueryableExtensions.FromSqlRaw[TEntity](DbSet`1 source, String sql, Object[] parameters)
at EFCoreShop.Program.Main(String[] args) in D:\Workspace\Learning\DotNet\EFCoreShop\EFCoreShop\Program.cs:line 14
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
namespace EFCoreShop
{
class Program
{
static void Main(string[] args)
{
using (ShopContext shopContext = new ShopContext())
{
//IEnumerable<BookInfo> bookInfos = shopContext.BookInfos.FromSqlRaw("exec GetBookInfos").ToList<BookInfo>();
//foreach (var bookInfo in bookInfos)
//{
// Console.WriteLine($"Book Id: {bookInfo.BookId} Book Name: {bookInfo.BookName} Author Name: {bookInfo.AuthorName}");
//}
// This is more manageable than stored procedure
IEnumerable<Book> books = shopContext.Books.Include( book => book.Author ).ToList();
foreach (var book in books)
{
Console.WriteLine($"Book Id: {book.BookId} Book Name: {book.Name} Author Name: {book.Author.FirstName+' '+book.Author.LastName}");
}
}
}
}
}
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Text;
namespace EFCoreShop
{
class ShopContext:DbContext
{
public DbSet<Author> Authors { get; set; }
public DbSet<Book> Books { get; set; }
public DbQuery<BookInfo> BookInfos { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Data Source=**********;Database=EFCoreShop;User ID=*********;Password=***********");
}
}
}