简体   繁体   English

C#EntityFramework Core-无效的对象名称,无法更新数据库

[英]C# EntityFramework Core - Invalid object name, cannot update database

  1. Added MDF database to project called FxTrader.mdf 将MDF数据库添加到名为FxTrader.mdf的项目中
  2. Created simple Model: 创建的简单模型:

     public class MarketTickContext : DbContext { public DbSet<MarketTickRecord> Records { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { string connectionString = @"Data Source = (LocalDB)\\MSSQLLocalDB; AttachDbFilename = ""C:\\Users\\asmodat\\Documents\\Visual Studio 2015\\Projects\\Asmodat FxTrader\\Asmodat FxTrader Data\\FxTrader.mdf""; Integrated Security = True"; optionsBuilder.UseSqlServer(connectionString); } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<MarketTickRecord>() .HasKey(mtr => new { mtr.Company, mtr.Symbol }); modelBuilder.Entity<MarketTickRecord>() .HasMany(mtr => mtr.Ticks); modelBuilder.Entity<MarketTick>() .HasKey(mt => mt.Time); } } 
  3. Run in console: Add-Migration MarketTickMigration.v3 -> success 在控制台中运行:Add-Migration MarketTickMigration.v3->成功

  4. Then Update-Database -> success 然后更新数据库->成功

But first. 但首先。 Database after this operation does not look like I expected. 此操作后的数据库看起来不像我预期的那样。 There should be 2 tables in my opinion: MarketTickRecord and MarketTick table 我认为应该有2个表:MarketTickRecord和MarketTick表

But only some wierd table appears, that looks like this. 但是只有一些奇怪的表出现,看起来像这样。

So when I run this code: 因此,当我运行此代码时:

_context = new MarketTickContext();
_context.Records.Add(new MarketTickRecord());
_context.SaveChanges();

The last line generates exception: 最后一行生成异常:

An unhandled exception of type 'Microsoft.EntityFrameworkCore.DbUpdateException' occurred in Microsoft.EntityFrameworkCore.dll

Additional information: An error occurred while updating the entries. See the inner exception for details.

{"Invalid object name 'Records'."}

same goes if I try: 如果我尝试也一样:

_context.Records.Count()

Can anybody point me to direction what am I doing wrong ? 有人能指出我在做什么吗? How can I update my database so it works ? 如何更新数据库使其正常工作?

EDIT ############################### -> Progress 编辑#############################->进度

I am slowly figuring out what is going on, so I created the simplest possible model to step by step check what is wrong. 我正在慢慢弄清楚发生了什么,因此我创建了最简单的模型来逐步检查问题所在。

public class TestContext : DbContext
    {
        public DbSet<TestRecord> Tests { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Asmodat_FxTrader_Data.MarketTicksDb.v14;Trusted_Connection=True;");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<TestRecord>()
                .HasKey(c => new { c.SomeK1, c.SomeK2 });
        }
    }

Above model is working great. 上面的模型效果很好。 So problem appears after creating new 'Test' class that will be placed inside list in TestRecord class, for example: 因此,在创建新的“ Test”类后会出现问题,该类将放置在TestRecord类的列表中,例如:

 public class TestRecord
    {

        public string SomeK1 { get; set; }

        public string SomeK2 { get; set; }

        public List<Test> Tests { get; set; }
    }

public class Test
    {

        public long SomeK1 { get; set; }

        public int V1 { get; set; }

        public int V2 { get; set; }
    }

If I now update OnModelCreating to this: 如果现在将OnModelCreating更新为:

protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<TestRecord>()
                .HasKey(c => new { c.SomeK1, c.SomeK2 });

            modelBuilder.Entity<Test>()
                .HasKey(c => c.SomeK1);
        }

The same exception appears as in original question.... 出现与原始问题相同的例外。

So problem, is somewhere here, and has to do with this List object or something missing in OnModelCreating. 所以问题就在这里,与这个List对象或OnModelCreating中缺少的东西有关。 Any ideas ? 有任何想法吗 ?

Edit ########################################## 编辑########################################

I also tried this, as suggested in the comments: 正如评论中所建议的,我也尝试过这样做:

protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            var tr = modelBuilder.Entity<TestRecord>();
                tr.HasKey(c => new { c.SomeK1, c.SomeK2 });
                tr.HasMany(c => c.Tests);
                tr.ToTable("Records");

            var t = modelBuilder.Entity<Test>();
                t.HasKey(c => c.SomeK1);
                t.ToTable("Tests");
        }

still the same problem remains only name inside error changes while tying to execute 仍然存在相同的问题,只是在执行过程中名称发生错误更改

TestContext con = new TestContext();
            con.Tests.Add(new TestRecord() { SomeK1 = "a1", SomeK2 = "a2", Tests = new List<Test>() });
            con.SaveChanges();

Edit ########################################## 编辑########################################

What I need is to have Many TestRecord's that can have many Test's inside them stored in list (One to Many). 我需要的是要有许多TestRecord,可以在其中存储许多测试(以一对多)。

But what is also required is that, lets say TestRecord with SomeK = {'a','b'}, and TestRecord with SomeK = {'c', 'd'}, might have Test's that have the same id, but are a different object (for example different V1 and V2). 但是还需要的是,比如说SomeRecord = {'a','b'}的TestRecord和SomeK = {'c','d'}的TestRecord可能具有相同ID的Test,但是一个不同的对象(例如,不同的V1和V2)。

For example (pseudocode): 例如(伪代码):

TestRecord['a','b'].Tests[1].v1 == 1
TestRecord['c','d'].Tests[1].v1 == 2

Is it possible ? 可能吗 ? does anyone knows how to achieve this with ef core flex API ? 有谁知道如何使用ef core flex API实现这一目标? Because all my tries are failing. 因为我所有的尝试都失败了。

I am currently using the entity framework in a school project and Ive had my fair share of weird things happen so I feel your pain. 我目前在学校项目中使用实体框架,而Ive发生了很多奇怪的事情,所以我感到您的痛苦。 I'm not sure what exactly your class looks like for MarketTickRecord or MarketTick, but one thing my professor had us add to our database objects were the data annotations [Table("YOUR_TABLE_NAME)"] above the 'public class ...' line and [Key] above the property in the class that would serve as the primary key. 我不确定您的MarketTickRecord或MarketTick的类到底是什么样子,但是我的教授让我们添加到数据库对象中的一件事是“ public class ...”行上方的数据注释[Table("YOUR_TABLE_NAME)"]并在类中位于属性上方的[Key]作为主键。 Also, we manually created our tables using the database designer in visual studio. 另外,我们使用Visual Studio中的数据库设计器手动创建了表。 Not sure if this will help you or not, but its worth a try! 不确定这是否对您有帮助,但值得一试!

Solution for future generations, don't use existing database - it must be created from scratch by ef core itself otherwise it will throw exceptions on save etc. 对于后代的解决方案,请勿使用现有数据库-必须由ef核心本身从头开始创建,否则它将在保存等情况下引发异常。

public class TestContext : DbContext
    {
        public DbSet<Test> Tests { get; set; }
        public DbSet<TestRecord> TestRecords { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            string connectionString = @"Server=(localdb)\mssqllocaldb;Database=Asmodat_FxTrader_Data.TestDb.v1;Trusted_Connection=True;";
            optionsBuilder.UseSqlServer(connectionString);
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            var tr = modelBuilder.Entity<TestRecord>();
            tr.HasMany(p => p.Tests).WithOne(x => x.TestRecord).HasForeignKey(p => p.TestRecordId);
        }
    }

    [Table("TestRecords")]
    public class TestRecord
    {
        public TestRecord()
        {
            this.Tests = new List<Test>();
        }

        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int TestRecordId { get; set; }

        public string SomeK1 { get; set; }

        public string SomeK2 { get; set; }

        public virtual ICollection<Test> Tests { get; set; }
    }

    [Table("Tests")]
    public class Test
    {
        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int TestId { get; set; }

        public int TestRecordId { get; set; }

        public virtual TestRecord TestRecord { get; set; }


        public long VT { get; set; }

        public int V1 { get; set; }

        public int V2 { get; set; }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM