【问题标题】:SqlException: Invalid object name Person.PersonSqlException:无效的对象名称 Person.Person
【发布时间】:2021-04-01 12:00:29
【问题描述】:

我正在按照this 教程使用 Visual Studio 2019 项目模板在 AspNet Core 3.1 中创建示例 API,但由于我使用的是 AdventureWorks (2019) 数据库,因此我不得不进行一些更改。

数据库上下文已像这样搭建

public partial class AdventureWorks2019Context : DbContext
{
   public AdventureWorks2019Context(){}

   public AdventureWorks2019Context(DbContextOptions<AdventureWorks2019Context> options)
            : base(options){}
   .
   .
   .
   public virtual DbSet<Person> Person { get; set; }
   .
   .
   .
}

然后我在 startup.cs 中注册了这个上下文,如下所示:

public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();

        services.AddDbContext<AdventureWorks2019Context>(
            options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
    }

我还搭建了一个 People 控制器,但是当我尝试 GetPerson() 方法时它不起作用,我得到一个 "SqlException: Invalid object name 'Person.Person'" 错误消息。

[HttpGet]
public async Task<ActionResult<IEnumerable<Person>>> GetPerson()
   {
     return await _context.Person.ToListAsync(); //==> SqlException: Invalid object name 'Person.Person'.
   }

这就是错误 SqlException: Invalid object name 'Person.Person'。 但是当我这样做(如下)时,它会起作用。但是,我不想这样做,因为我会错过依赖注入的全部意义,就像我看到的那样。

[HttpGet]
public async Task<ActionResult<IEnumerable<Person>>> GetPerson()
{
    AdventureWorks2019Context awc = new AdventureWorks2019Context();
    return await awc.Person.ToListAsync();//==> Works fine
}

在任何一种情况下,发送到 SQL Server 的都是这个,它工作正常。

SELECT [p].[BusinessEntityID], 
[p].[AdditionalContactInfo], 
[p].[Demographics], 
[p].[EmailPromotion], 
[p].[FirstName], 
[p].[LastName], 
[p].[MiddleName], 
[p].[ModifiedDate], 
[p].[NameStyle], 
[p].[PersonType], 
[p].[rowguid], 
[p].[Suffix], 
[p].[Title]
FROM [Person].[Person] AS [p]

我只是不知道这个错误是从哪里来的。 提前致谢

【问题讨论】:

  • 请确保您数据库中的表名与您定义的表名一致。
  • [Person].[Person]是什么,这张表的结构是什么?
  • 第一个[Person]指的是数据库模式,第二个是表。 [Schema].[Table] ==> [Person].[Person]

标签: asp.net-core dependency-injection database-schema datacontext asp.net-core-scaffolding


【解决方案1】:

长话短说,问题是我正在处理两个不同的连接字符串。

脚手架数据上下文使用的是硬编码的连接字符串,这没问题,所以当我手动创建上下文而不是注入它时它可以工作。

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    if (!optionsBuilder.IsConfigured)
    {
        optionsBuilder.UseSqlServer("Data Source=cougar-one\\dev01;Initial Catalog=AdventureWorks2019;Integrated Security=True");
    }
}

但是,当我继续在 StartUp.cs 上注册它时,我使用了一个名为“DefaultConnection”的连接字符串,它指向一个完全不同的数据库。

 public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();

        services.AddDbContext<AdventureWorks2019Context>(
            options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
    }

这就是注入上下文不起作用的原因。

【讨论】:

  • 可以通过重写 OnConfiguring 方法或通过构造函数参数在外部将 DbContextOptions 提供给 DbContext。如果两者都使用,则 OnConfiguring 最后应用,并且可以覆盖提供给构造函数参数的选项。
  • 你的代码中没有提供这个,但很高兴你能解决这个问题。
  • 是的,我已经学会了艰难的方式。谢谢。
猜你喜欢
  • 1970-01-01
  • 2017-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-29
相关资源
最近更新 更多