Invalid object name 'dbo.EdmMetadata' and 'dbo.__MigrationHistory' - entity-framework

I am using Entity Framework 5 and doing a simple query to get a few users from a table.
The SQL database is already created so I use my entities as a way to map what I have.
When I run my query I detect that other queries were executed and 2 of them with errors:
QUERY 1
ERROR: Invalid object name 'dbo.__MigrationHistory'.
SELECT
[GroupBy1].[A1] AS [C1]
FROM (
SELECT
COUNT(1) AS [A1]
FROM [dbo].[__MigrationHistory] AS [Extent1]
) AS [GroupBy1]
QUERY 2
ERROR: Invalid object name 'dbo.EdmMetadata'.
SELECT TOP (1)
[Extent1].[Id] AS [Id],
[Extent1].[ModelHash] AS [ModelHash]
FROM [dbo].[EdmMetadata] AS [Extent1]
ORDER BY [Extent1].[Id] DESC
Why is that?
I do not have dbo.EdmMetadata and dbo.__MigrationHistory tables in my database as the database already existed.
How to solve this?

Since the database is already there you will not have dbo.EdmMetadata and dbo.__MigrationHistory which codefirst is expecting. And to resolve this you can try to set the SetInitializer to null.
static NameOfYourContext()
{
Database.SetInitializer<NameOfYourContext>(null);
}
You can see this in the comments section of the this post by Scott Gu

There are 3 steps you need to follow:
1- Enable migrations in package manager if you haven't done yet:
Enable-Migrations
2- Add a migration and make sure to use the -IgnoreChanges switch as you already have an existing database:
Add-Migration InitialModel -IgnoreChanges
3- Update the database. This will automatically create __MigrationHistory table for you.
Update-Database

I disabled my exception setting. and it overlooked this exception and went on to create these tables for me automatically

Related

Redshift COPY throws error but 'stl_load_errors' system table does not provide details

When I attempt to copy a CSV from S3 into a new table in Redshift (which normally works for other tables) I get this error
ERROR: Load into table 'table_name' failed. Check 'stl_load_errors'
system table for details.
But, when I run the standard query to investigate stl_load_errors
SELECT errors.tbl, info.table_id::integer, info.table_id, *
FROM stl_load_errors errors
INNER JOIN svv_table_info info
ON errors.tbl = info.table_id
I don't see any results related to this COPY. I see errors from previous failed COPY commands, but none related to the most recent one that I am interested in.
Please make sure that you are querying stl_load_errors table with same user you are performing COPY command. You can also try to avoid using ssv_table_info table in query or change INNER to LEFT join.

Entity Framework Core - 2 Contexts in the same database - Second context tables are not created

I'm trying to use 2 contexts on the same database.
To create the database I'm using DbContext.Database.EnsureCreated()
The first EnsureCreated call works fine, the second EnsureCreated call does not work.
Some considerations
Profiling SQL Server I can see that EF Core checks for the existence of a table
IF EXISTS (
SELECT
*
FROM
INFORMATION_SCHEMA.TABLES
WHERE
TABLE_TYPE = 'BASE TABLE')
SELECT 1
ELSE
SELECT 0
then it runs the create table statement.
If there is a user table on the DB nothing is done...
Is there a way to force table creations from entities scaffolding?
Actually I found only this way.
RelationalDatabaseCreator databaseCreator =
(RelationalDatabaseCreator) context.Database.GetService<IDatabaseCreator>();
databaseCreator.CreateTables();
In my case it was because I failed to run add-migration SecondContext_Initial -Context SecondContext so there was no migration to run. Both EnsureCreated() (returned false) and Migrate() (did nothing) failed to yield any clues to my neglect.

AspIdentity EF and UserName

I've implemented what i consider a fairly standard ASP Identity using Entity Framework. I've added a couple of properties to the standard AspNetUser table but I have the username column as a non nullable column.
However when the SignInManager processes the PasswordSignInAsync it generated the following sql:
SELECT TOP (1)
[Extent1].[Id] AS [Id],
[Extent1].[FullName] AS [FullName],
[Extent1].[ClientId] AS [ClientId],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[LastName] AS [LastName],
[Extent1].[DateCreated] AS [DateCreated],
[Extent1].[UserOid] AS [UserOid],
[Extent1].[Email] AS [Email],
[Extent1].[EmailConfirmed] AS [EmailConfirmed],
[Extent1].[PasswordHash] AS [PasswordHash],
[Extent1].[SecurityStamp] AS [SecurityStamp],
[Extent1].[PhoneNumber] AS [PhoneNumber],
[Extent1].[PhoneNumberConfirmed] AS [PhoneNumberConfirmed],
[Extent1].[TwoFactorEnabled] AS [TwoFactorEnabled],
[Extent1].[LockoutEndDateUtc] AS [LockoutEndDateUtc],
[Extent1].[LockoutEnabled] AS [LockoutEnabled],
[Extent1].[AccessFailedCount] AS [AccessFailedCount],
[Extent1].[UserName] AS [UserName]
FROM [dbo].[AspNetUsers] AS [Extent1]
WHERE
(
UPPER([Extent1].[UserName]) = UPPER(#p__linq__0)
)
OR
(
(UPPER([Extent1].[UserName]) IS NULL)
AND (UPPER(#p__linq__0) IS NULL)
)
Can anyone tell me the following:
1. Why is EF generating the Is NULL clauses in the where clause when the username cannot be null?
2. How to stop this.
3. Is there anyway to stop the Upper statement for the Username?
1) this extra clause will be rulled out by SQL Server (presuming this is what you use) optimisation engine. But I suspect this is generated this way because your EF model does not have [Required] decorating Username property. And Username is a string and strings in .Net can be null. And when EF generates queries it does not check every column type - it looks on the the models(classes), so in EF eyes your Username column is nullable.
This is a good reason to use migrations and not modify the underlying DB by hand.
2) You see Upper because this is the way the linq query is written in the underlying storage in Identity (source, search for FindByNameAsync):
public virtual Task<TUser> FindByNameAsync(string userName)
{
ThrowIfDisposed();
return GetUserAggregateAsync(u => u.UserName.ToUpper() == userName.ToUpper());
}
.ToUppse() here is getting translated by EF into Upper in your SQL.
You can avoid this by implementing your own UserStore. But this might be too much work for what it is worth.

How to update (replace) a Postgis table?

I would like to "update" a "countries of the world"-postgis-table, by replacing it with another one which comes in form of a shapefile (dumped from a Postgis database) from my development server.
Now, I can't just do a "pgsql2shp", as this would throw an error as the table already exists. And renaming the existing table into something like "xx_original" doesn't work either ("xx_geom_gist already exists", is then the error message).
I don't want to delete the (old) table directly, as I would like to keep it as a backup.
So, what is the "right" way to solve this? Thanks for any hints!
If you are looking for an upsert functionality the obvious approach if you are on PostgreSQL 9.1 or higher is to copy the data into a temporary table and then use a CTE to update.
An example might be:
WITH upsert as (
UPDATE my_countries set shape = (select shape from temp_countries t
where t.name = my_countries.name)
WHERE name IN (select name from temp_countries)
RETURNING *
)
INSERT INTO my_countries
SELECT * FROM temp_countries
WHERE name NOT IN (select name from upsert);

OptimisticConcurrencyException -- SQL 2008 R2 Instead of Insert Trigger with Entity Framework

Using a SQL 2008 R2 November release database and a .net 4.0 Beta 2 Azure worker role application. The worker role collects data and inserts it into a single SQL table with one identity column. Because there will likely be multiple instances of this worker role running, I created an Insert Instead Of trigger on the SQL table. The trigger performs Upsert functionality using the SQL Merge function. Using T-SQL I was able to verify the insert instead of trigger functions correctly, new rows were inserted while existing rows were updated.
This is the code for my trigger:
Create Trigger [dbo].[trgInsteadOfInsert] on [dbo].[Cars] Instead of Insert
as
begin
set nocount On
merge into Cars as Target
using inserted as Source
on Target.id=Source.id AND target.Manufactureid=source.Manufactureid
when matched then
update set Target.Model=Source.Model,
Target.NumDoors = Source.NumDoors,
Target.Description = Source.Description,
Target.LastUpdateTime = Source.LastUpdateTime,
Target.EngineSize = Source.EngineSize
when not matched then
INSERT ([Manufactureid]
,[Model]
,[NumDoors]
,[Description]
,[ID]
,[LastUpdateTime]
,[EngineSize])
VALUES
(Source.Manufactureid,
Source.Model,
Source.NumDoors,
Source.Description,
Source.ID,
Source.LastUpdateTime,
Source.EngineSize);
End
Within the worker role I am using Entity Framework for an object model. When I call the SaveChanges method I receieve the following exception:
OptimisticConcurrencyException
Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.
I understand this is likly due to SQL not reporting back an IdentityScope for each new inserted/updated row. Then EF thinks the rows were not inserted and the transaction is not ultimately not committed.
What is the best way to handle this exception? Maybe using OUTPUT from the SQL merge function?
Thanks!
-Paul
As you suspected, the problem is that any insertions into a table with an Identity column are immediately followed by a select of the scope_identity() to populate the associated value in the Entity Framework. The instead of trigger causes this second step to be missed, which leads to the 0 rows inserted error.
I found an answer in this StackOverflow thread that suggested adding the following line at the end of your trigger (in the case where the item is not matched and the Insert is performed).
select [Id] from [dbo].[TableXXX] where ##ROWCOUNT > 0 and [Id] = scope_identity()
I tested this with Entity Framework 4.1, and it solved the problem for me. I have copied my entire trigger creation here for completeness. With this trigger defenition I was able to add rows to the table by adding Address entities to the context and saving them using context.SaveChanges().
ALTER TRIGGER [dbo].[CalcGeoLoc]
ON [dbo].[Address]
INSTEAD OF INSERT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT OFF;
-- Insert statements for trigger here
INSERT INTO Address (Street, Street2, City, StateProvince, PostalCode, Latitude, Longitude, GeoLoc, Name)
SELECT Street, Street2, City, StateProvince, PostalCode, Latitude, Longitude, geography::Point(Latitude, Longitude, 4326), Name
FROM Inserted;
select AddressId from [dbo].Address where ##ROWCOUNT > 0 and AddressId = scope_identity();
END
I had almost exactly the same scenario: Entity Framework-driven inserts to a view with an INSTEAD OF INSERT trigger on it were resulting in the "...unexpected number of rows (0)..." exception. Thanks to Ryan Gross's answer I fixed it by adding
SELECT SCOPE_IDENTITY() AS CentrePersonID;
at the end of my trigger, where CentrePersonID is the name of the key field of the underlying table that has an auto-inrcementing identity. This way the EF can discover the ID of the newly-inserted record.