Entity Framework throws exception - Invalid object

2019-01-12 05:06发布

问题:

I've followed Adam's answer here and the Entity Framework now works and the Seed() method also works.

But when I try to access the database like this:

    public User FindUserByID(int id)
    {
        return (from item in this.Users
                where item.ID == id
                select item).SingleOrDefault();
    }
  .............................................................................
    // GET: /Main/

    public ActionResult Index(int? id)
    {
        var db = UserDataBaseDB.Create();

        if (!id.HasValue)
            id = 0;

        return View(db.FindUserByID(id.Value));
    }

It throws an exception at return (from item in this.Users stating:

Exception Details: System.Data.SqlClient.SqlException: Invalid object name 'dbo.BaseCs'.

I've tried replacing it with: return this.Users.ElementAt(id); but then it throws this exception.

LINQ to Entities does not recognize the method 'MySiteCreator.Models.User ElementAt[User](System.Linq.IQueryable1[MySiteCreator.Models.User], Int32)' method, and this method cannot be translated into a store expression.`

Can anyone help me?
Thank you!

回答1:

Exception Details: System.Data.SqlClient.SqlException: Invalid object name 'dbo.BaseCs'

This error means that EF is translating your LINQ into a sql statement that uses an object (most likely a table) named dbo.BaseCs, which does not exist in the database.

Check your database and verify whether that table exists, or that you should be using a different table name. Also, if you could post a link to the tutorial you are following, it would help to follow along with what you are doing.



回答2:

It is most likely a mismatch between the model class name and the table name as mentioned by 'adrift'. Make these the same or use the example below for when you want to keep the model class name different from the table name (that I did for OAuthMembership). Note that the model class name is OAuthMembership whereas the table name is webpages_OAuthMembership.

Either provide a table attribute to the Model:

[Table("webpages_OAuthMembership")]
public class OAuthMembership

OR provide the mapping by overriding DBContext OnModelCreating:

class webpages_OAuthMembershipEntities : DbContext
{
    protected override void OnModelCreating( DbModelBuilder modelBuilder )
    {
        var config = modelBuilder.Entity<OAuthMembership>();
        config.ToTable( "webpages_OAuthMembership" );            
    }
    public DbSet<OAuthMembership> OAuthMemberships { get; set; }        
}


回答3:

If you are providing mappings like this:

 protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new ClassificationMap());
        modelBuilder.Configurations.Add(new CompanyMap());
        modelBuilder.Configurations.Add(new GroupMap());
        ....  
    }

Remember to add the map for BaseCs.

You won't get a compile error if it is missing. But you will get a runtime error when you use the entity.



回答4:

EF is looking for a table named dbo.BaseCs. Might be an entity name pluralizing issue. Check out this link.

EDIT: Updated link.



回答5:

It might me an issue about pluralizing of table names. You can turn off this convention using the snippet below.

 protected override void OnModelCreating(DbModelBuilder modelBuilder)
 {
     base.OnModelCreating(modelBuilder);
     modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
 }


回答6:

If everything is fine with your ConnectionString check your DbSet collection name in you db context file. If that and database table names aren't matching you will also get this error.

So, for example, Categories, Products

public class ProductContext : DbContext 
{ 
    public DbSet<Category> Categories { get; set; } 
    public DbSet<Product> Products { get; set; } 
}

should match with actual database table names:



回答7:

You have to define both the schema and the table in two different places.

the context defines the schema

public class BContext : DbContext
{
    public BContext(DbContextOptions<BContext> options) : base(options)
    {
    }

    public DbSet<PriorityOverride> PriorityOverrides { get; set; }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.HasDefaultSchema("My.Schema");

        builder.ApplyConfiguration(new OverrideConfiguration());
    }
}

and for each table

class PriorityOverrideConfiguration : IEntityTypeConfiguration<PriorityOverride>
{
    public void Configure(EntityTypeBuilder<PriorityOverride> builder)
    {
        builder.ToTable("PriorityOverrides");
        ...
    }
}


回答8:

Instead of

modelBuilder.Entity<BaseCs>().ToTable("dbo.BaseCs");

Try:

modelBuilder.Entity<BaseCs>().ToTable("BaseCs");

even if your table name is dbo.BaseCs



回答9:

In the context definition, define only two DbSet contexts per context class.