Entity code first migration try to drop old table - entity-framework

I added some entities to my context.And then i migrate them as a below with my tool
using (var db = new TourismContext())
{
if (db.Database.CompatibleWithModel(true))
return;
var initializer = new MigrateDatabaseToLatestVersion<TourismContext, TourismContextConfiguration>();
initializer.InitializeDatabase(db);
//and other code.....
it drop tables which i removed them from my context.And it works.it is compatible.But after 20 minutes it says non compatible.it want to drop some tables but this tables are not existing
what should i do?
although i remove that tables from context and migrate it(migration tool drop that tables from database) why it want to drop them again and again?the tables that migration want to drop is not existing in database.because i migrate them so migration tool drop them.Where migration get that tables info to drop?
this is my __MigrationHistory
SELECT TOP 1000 [MigrationId]
,[Model]
,[ProductVersion]
,[CreatedOn]
FROM [TOURISM_new1].[dbo].[__MigrationHistory]
there is no droping tables info here
here is my migration tool.There is two buton.one show scritp which will show executed script(script button) other is micration buton.it migrate
private void MigrateButton_Click(object sender, EventArgs e)
{
try
{
using (var db = new TourismContext())
{
if (db.Database.CompatibleWithModel(true))
return;
var initializer = new MigrateDatabaseToLatestVersion<TourismContext, TourismContextConfiguration>();
initializer.InitializeDatabase(db);
foreach (Constants.SecurityFeatureIdentifier securityFeatureIdentifier in Enum.GetValues(typeof(Constants.SecurityFeatureIdentifier)))
{
if (db.SecurityFeatures.All(sf => sf.SecurityFeatureIdentifierID != (int)securityFeatureIdentifier))
{
db.SecurityFeatures.Add(new SecurityFeature { SecurityFeatureIdentifier = securityFeatureIdentifier });
db.SaveChanges();
}
}
}
statusLabel.Text = "Compatible";
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private void ScriptButton_Click(object sender, EventArgs e)
{
try
{
using (var db = new TourismContext())
{
if (db.Database.CompatibleWithModel(true))
return;
var migrator = new DbMigrator(new TourismContextConfiguration());
var scriptor = new MigratorScriptingDecorator(migrator);
scriptControl.Text = scriptor.ScriptUpdate(null, null);
foreach (Constants.SecurityFeatureIdentifier securityFeatureIdentifier in Enum.GetValues(typeof(Constants.SecurityFeatureIdentifier)))
{
if (db.SecurityFeatures.All(sf => sf.SecurityFeatureIdentifierID != (int)securityFeatureIdentifier))
{
db.SecurityFeatures.Add(new SecurityFeature { SecurityFeatureIdentifier = securityFeatureIdentifier });
db.SaveChanges();
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}

You need to get your database model in sync with your code first model. You could either comment out the obsolete code from the Up() method of the migration and do an update-database or you can remove the pending migration and do Add-Migration MyBaseline –IgnoreChanges with an update-database. Now you should be compatible until you change your model.
https://msdn.microsoft.com/en-us/data/dn579398.aspx?f=255&MSPPError=-2147217396#option1

Related

Apply migration on multiple schemas using Java and Liquibase

I'm trying to apply migration over my multi tenant system where I have one database with multiple schemas,
And I do so by first getting all the tenants then loop over them and execute the update on liquibase after changing the schema, but it seems that the schema is not changed cause after performing the migration on the first tenant the second tenant throws an error complaining about table already exist.
#Override
#SneakyThrows
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
Connection connection = null;
Statement statement = null;
Liquibase liquibase = null;
try {
connection = dataSource.getConnection();
statement = connection.createStatement();
ResultSet result = statement.executeQuery("SELECT nspname FROM pg_namespace WHERE nspname like 'tenant_%'");
List<String> schemas = new ArrayList<>();
while (result.next()) {
schemas.add(result.getString(1));
}
for (String schemaName:schemas) {
connection.setSchema(schemaName);
Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(connection));
database.setDefaultSchemaName(schemaName);
log.info("Schema Name: {}",connection.getSchema());
liquibase = new Liquibase(CHANGE_LOG_FILE, new ClassLoaderResourceAccessor(), database);
liquibase.update(new Contexts(), new LabelExpression());
}
} catch (SQLException | DatabaseException e) {
e.printStackTrace();
}finally {
if(liquibase!=null) {
liquibase.close();
}
if(statement!=null&&!statement.isClosed()) {
statement.close();
}
if(connection!=null&&!connection.isClosed()){
connection.close();
}
}
}
Note: the reason I made it in different loops and not using `try-with-resource` is that the connection closes after getting the first row of the result set and updating the database so I had to close it myself

Duplicate primary key when inserting using EF5

When I am trying to insert some value using this code I am getting the error below:
{"ORA-00001: unique constraint (NCOREDB.PK_NCORE_CASH_IN) violated"}
I am using EF5 and Oracle as Database.It was working fine a while ago. I can not update my EF because of some dependency issue.
using (TransactionScope transactionScope = new TransactionScope())
{
try
{
NCORE_TRN_CASH_IN_INFO OBJ_NCORE_TRN_CASH_IN_INFO = new NCORE_TRN_CASH_IN_INFO();
int id = Convert.ToInt32(Obj_nCoreEntities.NCORE_TRN_CASH_IN_INFO.Max(t => (int?)t.CASH_IN_ID)) + 1;
OBJ_NCORE_TRN_CASH_IN_INFO.CASH_IN_ID = id;
//Inserting other value here
Obj_nCoreEntities.NCORE_TRN_CASH_IN_INFO.Add(OBJ_NCORE_TRN_CASH_IN_INFO);
Obj_nCoreEntities.SaveChanges();
transactionScope.Complete();
}
catch (DbEntityValidationException dbEx)
{
transactionScope.Dispose();
string inner = ExceptionExtendedMethods.GetDBInnerExceptions(dbEx);
return inner;
}
catch (Exception ex)
{
transactionScope.Dispose();
string inner4 = ExceptionExtendedMethods.GetInnerExceptions(ex);
return inner4;
}
}

One to Many And Many To One Insert in Ef 6.0

A doctor have one degree and one degree have many doctors,
well when i try to add new doctor ef 6.0 (DbContext) insert the selected degree as new record in Degress Table
i don know why ?
Insert Method :
public bool Insert<T>(T entity) where T : class
{
bool result = false;
try
{
Context.Set<T>().Add(entity);
result = Context.SaveChanges() > 0;
}
catch (Exception exp)
{
result = false;
fnLogExceptions(exp);
}
return result;
}
The insert Section :
private void btnSave_Click(object sender, EventArgs e)
{
var dr = new DB.Doctors();
...
dr.Degrees = dropDownList_Degree.SelectedItem as DB.Degrees;
...
using (var ctx = new Context())
{
opState = ctx.Insert<DB.Doctors>(dr);
}
...
}
the new doctor is inserted successfully but also it insert new copy of selected degree
thanks in advance
The Degree that you were trying to assign isn't from the database, its from the dropodown list. So the EF thinks its new, therefore inserting a new Degree.
You need to retrieve the existing degree from the database.
var dr = new DB.Doctors();
int selectedDegreeID = (int)dropDownList_Degree.SelectedItem.Value;
using (var ctx = new Context())
{
dr.Degree = ctx.Degrees.Find(selectedDegreeID); // Retrieval and assignment.
opState = ctx.Insert<DB.Doctors>(dr);
}

Update only scalar properties in Code First, EF 5

God day!
I have a tree of entities and at specific point of time i need to update only scalar properties of one entity. Classic update rise entire graph lookup, but relations not need to update.
The trouble in Category entity what one category have another categories in children. My method generate exceptions when saving changes about duplicate key. I think EF try to add children to database.
Static method of my data context listed below:
public static void Update<T>(T item) where T : KeyedObject
{
if (item == null)
throw new ArgumentNullException("Item to update is null");
item.ValidateIsNotNew();
using (DataContext db = new DataContext())
{
T original = GetOriginalWithException<T>(db, item);
DbEntityEntry entry = db.Entry(original);
entry.CurrentValues.SetValues(item);
entry.State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (Exception ex)
{
throw new DatabaseException(
"Cant update list item. See inner exception for details.",
ex);
}
}
}
I tries another method: attaching object. This method does not throw exception, but it rise entire graph update and take many resources. Code listed below:
public static void Update<T>(T item) where T : KeyedObject
{
if (item == null)
throw new ArgumentNullException("Item to update is null");
item.ValidateIsNotNew();
using (DataContext db = new DataContext())
{
db.Set<T>().Attach(item);
db.Entry(item).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (Exception ex)
{
throw new DatabaseException(
"Cant update list item. See inner exception for details.",
ex);
}
}
}

Inserting record instead of updating

I am developing an MVC app.
When I try to updated record it showing error of DBEntityValidation exception,
( beacuse its trying to add record in DB. This is my code)
public JsonResult SavePassword(int EmpId, string Password)
{
try
{
Employee e1 = db.Employees.First(i => i.Id == EmpId);
db.Entry(e1).State = EntityState.Modified;
e1.Password = Password;
db.SaveChanges();
return Json(EmpId);
}
catch (DbEntityValidationException e)
{
foreach (var eve in e.EntityValidationErrors)
{
Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
eve.Entry.Entity.GetType().Name, eve.Entry.State);
foreach (var ve in eve.ValidationErrors)
{
Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"", ve.PropertyName, ve.ErrorMessage);
}
}
throw;
}
}
In exception, it shows that validation msgs, which I have checked while adding new record.
So , I think its trying to add in DB insted of updating.