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

时间:2017-02-20 18:04:05

标签: c# mysql entity-framework

  1. 将MDF数据库添加到名为FxTrader.mdf
  2. 的项目中
  3. 创建简单模型:

    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);
    }
    }
    
  4. 在控制台中运行:添加迁移MarketTickMigration.v3 - &gt;成功

  5. 然后更新 - 数据库 - &gt;成功
  6. 但首先。此操作后的数据库看起来不像我预期的那样。 我认为应该有2个表:MarketTickRecord和MarketTick表

    But only some wierd table appears, that looks like this.

    所以当我运行这段代码时:

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

    最后一行生成异常:

    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'."}
    
    如果我尝试的话也一样:

    _context.Records.Count()
    

    有人能指出我的方向我做错了吗? 如何更新我的数据库以使其有效?

    编辑############################### - &gt;进展

    我正在慢慢弄清楚发生了什么,所以我创建了最简单的模型来逐步检查出了什么问题。

    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 });
            }
        }
    

    以上型号效果很好。因此,在创建将放置在TestRecord类的列表中的新“Test”类之后会出现问题,例如:

     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; }
        }
    

    如果我现在将OnModelCreating更新为:

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

    出现与原始问题相同的异常....

    所以问题就在这里,并且与这个List对象或OnModelCreating中缺少的东西有关。有什么想法吗?

    编辑##########################################

    我也按照评论中的建议尝试了这个:

    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");
            }
    

    在绑定执行

    时,仍然只有同样的问题仍然存在错误更改内的名称
    TestContext con = new TestContext();
                con.Tests.Add(new TestRecord() { SomeK1 = "a1", SomeK2 = "a2", Tests = new List<Test>() });
                con.SaveChanges();
    

    编辑##########################################

    我需要的是拥有许多TestRecord,它们里面可以有许多Test存储在列表中(一对多)。

    但是,还需要的是,让我们说TestRecord与SomeK = {'a','b'}和TestRecord与SomeK = {'c','d'},可能有测试具有相同的id ,但是是不同的对象(例如不同的V1和V2)。

    例如(伪代码):

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

    有可能吗?有谁知道如何使用ef core flex API实现这一目标?因为我的所有尝试都失败了。

2 个答案:

答案 0 :(得分:0)

我目前正在学校项目中使用实体框架,并且我有一些奇怪的事情发生,所以我感到痛苦。我不确定您的课程对于MarketTickRecord或MarketTick究竟是什么样的,但我教授给我们添加到数据库对象的一件事是“公共类......”行上方的数据注释[Table("YOUR_TABLE_NAME)"]和{{ 1}}在类中作为主键的属性之上。此外,我们使用visual studio中的数据库设计器手动创建了表。不确定这对你有没有帮助,但值得一试!

答案 1 :(得分:-1)

为子孙后代解决方案,不要使用现有的数据库 - 它必须由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; }
    }