EF CTP5 error: Invalid object name - asp.net-mvc-2

I followed the example on scottgu's blog about EF code first CTP5 but I get the error that
System.Data.SqlClient.SqlException:
Invalid object name 'dbo.Products'.
this is the code I got.
<add name="CTP5Context"
connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|EFCTP5.mdf;User Instance=true"
providerName="System.Data.SqlClient" />
public class CTP5Context : DbContext
{
public DbSet<Product> Products { get; set; }
}
public class Product
{
public int Id { get; set; }
public string ProductName { get; set; }
public int Amount { get; set; }
}
var context = new CTP5Context();
var products = context.Products;
return View(products);
im kinda clueless here I done the same as the blogpost, its not my first time with EF (But CTP5 tho), I'm I overlooking something?

If your table name is Product in the database, try this:
[Table("Product", SchemaName = "dbo")]
public class Product
{
public int Id { get; set; }
public string ProductName { get; set; }
public int Amount { get; set; }
}
To use the Table attribute You will need to add the following using statement:
using System.ComponentModel.DataAnnotations;
Hope this helps! It worked for me.

I had the same problem but I've done 2 changes and it works for me. I changed connection string (Added initial catalog)
<add name="CTP5Context"
connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\northwind.mdf;User Instance=true;initial catalog=Northwind"
providerName="System.Data.SqlClient" />
and in the Global.asax I've added following line in Application_Start()
Database.SetInitializer<Northwind>(new System.Data.Entity.DropCreateDatabaseAlways<Northwind>());

The exception looks like it's coming from the database. Are you sure your table name is 'Products' or is it 'Product' (singular instead of plural?)

It seems EF Code First works differently depending on which type of database you're connecting to. If you work with SQLCE which is what ScottGu is using to showcase EF Code First, then all tables will be created with names that are not plural. However, if you use SQL Server 2008 (that's what I tested with), it expected tables names to be plural. There are few ways around this, you could add the table name attribute as Omar shows, or you could override the OnModelCreating event for the context.
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
base.OnModelCreating(modelBuilder);
}

Make sure your Products table was created with the dbo Schema, a lot of times the schema will be something other than dbo, such as it can be your username or server name (if the account you're working with isnt in the db_owner schema). Open up the DB (since it's SQLExpress) with Server Explorer in Visual Studio)
To do this right click on the table name and select Open Table Definition then inside the table definition right click and select Properties and in the properties window check what is listed in the schema value. If it's not DBO then you should be able to change it to dbo and save it.

Related

add-migration queries the database for the columns I'm trying to add, fails with "Error: Invalid column name 'newColumn1', 'newColumn2', 'newColumn3'"

I'm trying to add three columns to an existing table via code first migrations with EF Core (package version 3.1.8). When I run add-migration <name> -c <context> -o <output folder>, it's throwing this error (along with a massive stack trace...):
An error occurred while accessing the Microsoft.Extensions.Hosting services. Continuing without the
application service provider. Error: Invalid column name 'NewColumn1'.
Invalid column name 'NewColumn2'.
Invalid column name 'NewColumn3'.
Unable to create an object of type 'MyDbContext'. For the different patterns supported at
design time, see https://go.microsoft.com/fwlink/?linkid=851728
Really baffled by this. This is the fourth migration I've added today, none of the previous ones had this issue.
This migration should add the three columns, data for the predefined rows for these columns, and add a default value constraint to newColumn1. The column data types:
newColumn1: bit, defaults to 0
newColumn2: nvarchar(50)
newColumn3: nvarchar(50)
My entity before adding my trouble migration:
public class MyEntity
{
[Key]
public int Id { get; set; }
[MaxLength(50), Required]
public string AttributeName { get; set; }
[Required]
public bool Required { get; set; }
}
This entity changed to the following prior to attempting to add this migration:
public class MyEntity
{
[Key]
public int Id { get; set; }
[MaxLength(50), Required]
public string AttributeName { get; set; }
[Required]
public bool Required { get; set; }
public bool NewColumn1{ get; set; }
[MaxLength(50)]
public string NewColumn2 { get; set; }
[MaxLength(50)]
public string NewColumn3 { get; set; }
}
In MyDbContext.OnModelCreating, I have the following new code:
builder.Entity<MyEntity>().Property(x => x.NewColumn1).HasDefaultValue(false);
The IEntityTypeConfiguration<MyEntity> has also, as previously mentioned, been updated to have data for all new columns for the predefined rows. No rows exist in the database besides the predefined rows.
I have a theory as to what's going on. I think add-migration requires an instance of MyDbContext, and when it gets instantiated it verifies that the database looks the way it expects. The context expects the table represented by MyEntity to have the three new columns that are defined in the entity, but they don't exist in the database. What I'm curious of is why this just started now? This is my fourth migration of the day, my other migrations added tables, columns, data....why would this just now start becoming an issue?
The msft documentation link in the error makes me think I need to implement IDesignTimeDbContextFactory<MyDbContext>, configure it in such a way that it makes it not choke. But looking at the behavior of DbContextOptionsBuilder, it doesn't look like any of the provided options will allow me to bypass the behavior I'm getting.
The database has been updated with all previous migrations, and I checked the DbContextModelSnapshot file...the new columns aren't anywhere in there (as expected). The database I'm targeting is a local SQL Server database.

Using DbGeography with EF6 + SqlServerCe.4.0 (.sdf database). Theoretically possible but not working

According to this:
http://msdn.microsoft.com/en-us/library/ms172417.aspx, it is possible to use "DbGeography", because it will be mapped to "image" in the database side. (As when using enums, they are mapped to ints)
However,
If I have this:
public class Something
{
public long SomethingId { get; set; }
public string Name { get; set; }
public DbGeography Location { get; set; }
}
When the database is created for the first time (using EF6 with "Code First" approach), I get this exception:
There is no store type corresponding to the EDM type 'Edm.Geography(Nullable=True)' of primitive type 'Geography'.
My connection string is the following:
<add name="MyDbContext" connectionString="Data Source=|DataDirectory|MyDatabase.sdf" providerName="System.Data.SqlServerCe.4.0" />
What am I doing wrong?
I checked and my EF's dll is version 6
You cannot do this, the MSDN article Refers to the fact that the replication component move data in this column type to a "image" column in SQL Compact.
You must use:
[MaxLength]
public byte[] Location { get; set; }
to store the data, and use the Spatial libraries to convert back and forth in your app

Entity framework code-first ignores table mapping

We have a ef project using an existing legacy database, but adding new tables to it using ef-migrations. For these entities, we create tables using a new schema, to separate them from the legacy tables. We use the convention with plural form of the class name on the db tables.
However, when we add a new class to be mapped to a legacy table (without a plural table name), ef seems to ignore the mapping.
The entity class:
public class Aktor:IVersionedEntityWithId
{
public int Id { get; set; }
public string Navn { get; set; }
public byte[] Version { get; set; }
}
The mapping code:
protected virtual void MapAktor(EntityTypeConfiguration<Tilsyn.Domain.Aktor> config){
config.ToTable("dbo.Aktor");
config.Property(v=>v.Version).IsConcurrencyToken().IsRowVersion();
config.HasKey(e=>e.Id);
}
The exception:
System.Data.EntityCommandExecutionException: An error occurred while
executing the command definition. See the inner exception for details.
---> System.Data.SqlClient.SqlException: Invalid object name 'dbo.Aktors'.
It seems like the sql generated still ad an s to the class name to get the table name. What is missing in this picture? Am I using the ToTable method wrong?
Update: When changing the class name to something other than the table name, it seems to work. When changing the name back again, the problem has vansihed. Is there a EF cache or hidden mapping file somwehere?
Try overriding OnModelCreating() method in your DBContext subclass to create your mappings.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Tilsyn.Domain.Aktor>().ToTable("dbo.Aktor");
}

Entity Framework 4.1Code First connecting to Sql Server 2005

I'm trying to use the Entity Framework 4.1 RC with a SQL Server 2005 instance. I've created an empty database and I'd like to persist my POCO objects to it. My POCO looks like:
public class Cart
{
public Cart()
{
this.CartId = Guid.NewGuid();
}
public Guid CartId { get; set; }
public decimal TotalCost { get; set; }
public decimal SubTotalCost { get; set; }
public decimal Tax { get; set; }
public decimal EstimatedShippingCost { get; set; }
}
My CartContext is:
public class CartContext : DbContext
{
public DbSet<Cart> Carts { get; set; }
public DbSet<Attribute> Attributes { get; set; }
public DbSet<AttributeItem> AttributeItems { get; set; }
}
I have a connection string:
<add name="CartContext" connectionString="Server=myserver.mynetwork.net;User ID=MyUser;Pwd=mypassword;Initial Catalog=ExistingDb" providerName="System.Data.SqlClient" \>
When I try and add an object to the context and save it I get:
System.Data.Entity.Infrastructure.DbUpdateException:
An error occurred while updating the
entries. See the inner exception for
details. --->
System.Data.UpdateException: An error
occurred while updating the entries.
See the inner exception for details.
---> System.Data.SqlClient.SqlException:
Invalid object name 'dbo.Carts'.
If I profile the database I can see the user connect, look for the database in sys.tables run this query:
SELECT TOP (1)
[Extent1].[Id] AS [Id],
[Extent1].[ModelHash] AS [ModelHash]
FROM [dbo].[EdmMetadata] AS [Extent1]
ORDER BY [Extent1].[Id] DESC
Then attempt to insert my cart object. It never tries to create the Carts table. I'm guessing there's something wrong with the connection string, but I can't find examples anywhere on how to do this.
DbContext will not create table just because it doesn't exists. Once you are using existing database you must also manually create tables or create custom initializer. Default initializers are only able to drop the database and create new one with all required tables.
You can for example call:
context.Database.Delete();
context.Database.Create();
Or:
context.Database.CreateIfNotExists();
Or:
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<MyContext>());
// You don't need to call this. Initialization takes place anyway if context
// needs it but you can enforce initialization for example in the application
// startup instead of before the first database operation
context.Database.Initialize(true);

EF Code First giving me error Cannot insert explicit value for identity column in table 'People' when IDENTITY_INSERT is set to OFF. [duplicate]

This question already has answers here:
EF code first: Cannot insert explicit value for identity column in table '' when IDENTITY_INSERT is set to OFF
(3 answers)
Closed 4 years ago.
I'm trying out Entity Framework 4's Code First (EF CodeFirst 0.8) and am running into a problem with a simple model that has a 1 <--> 0..1 relationship, between Person and Profile. Here's how they're defined:
public class Person
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime? DOB { get; set; }
public virtual Profile Profile { get; set; }
}
public class Profile
{
public int ProfileId { get; set; }
public int PersonId { get; set; }
public string DisplayName { get; set; }
public virtual Person Person { get; set; }
}
The DB context looks like this:
public class BodyDB : DbContext
{
public DbSet<Person> People { get; set; }
}
I didn't define a DbSet for Profile because I consider People to be its aggregate root. When I try to add a new Person - even one without a Profile with this code:
public Person Add(Person newPerson)
{
Person person = _bodyBookEntities.People.Add(newPerson);
_bodyBookEntities.SaveChanges();
return person;
}
I get the following error:
Cannot insert explicit value for identity column in table 'People' when IDENTITY_INSERT is set to OFF.
The newPerson object has a 0 for the PersonId property when I call People.Add(). The database tables are People and Profiles. PersonId is the PK of People and is an auto-increment Identity. ProfileId is the PK of Profiles and is an auto-incement Identity. PersonId is a non-null int column of Profiles.
What am I doing wrong? I think I'm adhering to all the EF Code First's convention over configuration rules.
I get the following error:
Cannot insert explicit value for identity column in table 'People' when IDENTITY_INSERT is set to OFF.
I think that the IDENTITY_INSERT is the Auto Increment functionality which is off.
So, check the field PersonId in the database to see if it is an identity.
Besides, maybe this will fix your problem too.
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int PersonId { get; set; }
This will occur if you perform the following steps:
Create a non-identity PK field on a table.
Infer the Entity Model from that table.
Go back and set the PK identity to true.
The Entity Model and the database are out of sync. Refreshing the model will fix it. I had to do this just yesterday.
If you are using EF Code First, then, in addition to adding the [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] annotation attribute to the model.cs file as others have suggested here, you also need to make the same effective change on the modelMap.cs files (the fluent mapping instructions):
Change from:
this.Property(t => t.id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
to:
this.Property(t => t.id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
(I used the EF Power Tools to generate the entity models and the default mapping files, then later turned one Id column into a prmary key column and set it to IDENTITY in Sql Server, therefore, I had to update the attribute and the default mapping file.)
If you don't change it in both places, you'll still get the same error.
You situation reminds me situation I experience with EF Code First when PrimaryKey and ForeignKey are the same column.
There is no direct way to refresh the model, however the same effect can be achieved in 2 steps.
Comment out ProfileId in Profile class. Recompile and update database.
Uncomment Profile Id, add DatabaseGeneratedAttribute and update database again.
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.None), Key]
This way the generated ProfileId column becomes Key without Identity.
If you are using EF core and the fluent interface like me, I've found that the Scaffold-DbContext utility I've used to create the model from an existing db, generate a line for my column like that:
entity.Property(e => e.id).ValueGeneratedNever();
After I've changed the DB adding the IDENTITY attribute to my id, I had to change the row in:
entity.Property(e => e.id).ValueGeneratedOnAdd();
other than adding the [DatabaseGeneratedAttribute(DatabaseGeneratedOption.None), Key] decorator to the id field in my model class.
I'm not even sure if the latter is necessary. After resolved with the former fix, I didn't try to remove it.
I didn't have this problem until I added a composite key , so once I had 2 primary keys this occurred with EF 6.x.x
On my Key "Id" which has Identity Specification set to true I needed to add
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
Model properties now:
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
[Key, Column("Id", Order = 1)]
public int Id { get; set; }
[Key, Column("RanGuid", Order = 2)]
public string RanGuid { get; set; }
For the benefit of searchers: I got this error, but the above fixes did not work. It was due to an error on my part.
On my tables, I have a Guid Primary Key (non-clustered) and an int index.
The error was happening when trying to update the 'Post' with the 'Blog' info as a navigation property. See classes below:
public class Blog
{
public Guid BlogId { get; set; }
public int BlogIndex { get; set; }
// other stuff
}
public class Post
{
public Guid PostId { get; set; }
public int PostIndex { get; set; }
// other stuff
public Blog Blog { get; set; }
}
The issue was that when I was converting DTO's to models, the BlogId was being changed to a new Guid() (I made an error in the mapping). The resulting error was the same as detailed in this question.
To fix it, I needed to check the data was right when being inserted (it wasn't) and fix the incorrect change of data (in my case, the broken mapping).
Got this error in EF6, looked at the database and everything looked right with Identity Specification set to Yes. I then removed the different migrations and made one new migration from current models and then everything started working. Fastest solution since the application was not live yet and still in development.
Cannot insert explicit value for identity column in table
'Test' when IDENTITY_INSERT is set to OFF.
Here is the solution. Also see the attachment for more help.
Navigate to your EF model ".edmx" file >> Open it >> Now right click on the diagram and choose 'Update Model from Database'.
This will fix it because you made PK the Identity in your DB after you created your EF model.
help to recreate steps stated above
In my case it seems that EF doesn't like other type than INT identity field - mine was a BYTE (TINYINT on the SQL side).
Since I was able to update my project and change it to INT on the SQL, after re-running the Reverse Engineering Code First on VisualStudio, the error has immediately ceased to occur.
In my case it seems that EF doesn't like other type than INT identity field - mine was a BYTE (TINYINT on the SQL side).
I had this error too using PK of tinyint type. It's not that EF doesn't like it, it's seems that, unlike other cases, you have to specify that in your configuration like this:
this.Property(t => t.TableID).HasColumnName("TableID").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);