Upgarde from EF 6 to EF Core - entity-framework

I am trying to upgrade my project to .net Core 2.0,
I am unable to think any solution to change the below lines.
Old Implementation:
public void ResetChangeTracking<T>(T model) where T : class, ICloneable, ICommonModel
{
// We might get called with a null model. If so, just return.
if (model == null) return;
// Calling ObjectContext.GetObjectType helps when DynamicProxies are being used.
// https://msdn.microsoft.com/en-us/data/jj592886.aspx
string key = $"{ObjectContext.GetObjectType(model.GetType())}-{model.Id}";
if (_originalValues.ContainsKey(key))
{
_originalValues.Remove(key);
}
}
How to make this work in .net Core 2.0?
Thanks

Related

EF Core APIs removed, now how to remove automatic pluralization?

(This is not a dupe, please read my comment.)
I've just migrated from EF Core Preview 5 to Preview 6.
This seems to be a breaking change, especially the mapping will break to the existing Databases if this remains in the release version.
In preview 5 I used:
entityType.Relational.TableName = entityType.DisplayName();
Now it seems Relational property was removed. I would not fall back to manually declare the TableName for all dozens of entities, instead just instruct EF Core model builder do not pluralize automatically them.
EF Core 3 introduces, starting preview6, breaking changes on Provider-specific Metadata API. This includes removal of RelationalMetadataExtensions together with its extension methods such as Relational(this IMutableEntityType entityType).
It is replaced by RelationalEntityTypeExtensions where you can do the following:
IMutableEntityType entity = ...;
entity.SetTableName(entity.DisplayName());
With that, removing automatic pluralization can be done as described in this answer on a related question
using Microsoft.EntityFrameworkCore.Metadata;
public static class ModelBuilderExtensions
{
public static void RemovePluralizingTableNameConvention(this ModelBuilder modelBuilder)
{
foreach (IMutableEntityType entity in modelBuilder.Model.GetEntityTypes())
{
entity.SetTableName(entity.DisplayName());
}
}
}
Improved version of Jan Paolo Go's Answer This prevents intermediate table to become something like TeacherStudent Dictionary<string, object>
public static class ModelBuilderExtensions
{
public static void RemovePluralizingTableNameConvention(this ModelBuilder modelBuilder)
{
foreach (IMutableEntityType entity in modelBuilder.Model.GetEntityTypes())
{
if (entity is EntityType { IsImplicitlyCreatedJoinEntityType: true })
{
continue;
}
entity.SetTableName(entity.DisplayName());
}
}
}

Using annotations to flow information from model building to migrations in EF Core

For EF Core. Related to this issue on the repo.
How do I "flow information" from the model building to the migrations stages in EF Core?
That issue was discussed among the authors who obviously fully understand the internals of EF Core, but I don't. How do I implement this?
First, flow your annotation from the model into the migration operations. Do this by overriding the provider-specific IMigrationsAnnotationProvider service.
class MyMigrationsAnnotationProvider : SqlServerMigrationsAnnotationProvider
{
public override IEnumerable<IAnnotation> For(IProperty property)
=> base.For(property)
.Concat(property.GetAnnotations().Where(a => a.Name == "MyAnnotation"));
}
Second, use the annotation in the provider-specific IMigrationsSqlGenerator service to generate DDL.
class MyMigrationsSqlGenerator : SqlServerMigrationsSqlGenerator
{
protected override void Generate(
AddColumnOperation operation,
IModel model,
MigrationCommandListBuilder builder)
{
var myAnnotation = operation.FindAnnotation("MyAnnotation");
if (myAnnotation != null)
{
// TODO: Add custom SQL using builder
}
}
}
Finally, configure your context to use your services.
optionsBuilder.UseSqlServer(connectionString)
.ReplaceService<SqlServerMigrationsAnnotationProvider, MyMigrationsAnnotationProvider>()
.ReplaceService<SqlServerMigrationsSqlGenerator, MyMigrationsSqlGenerator>();

Entity Framework Core 1.0 CurrentValues.SetValues() does not exist

I'm attempting to update an entity and its related child entities using Entity Framework Core 1.0 RC 1, where the entities are detached from DbContext. I've done this previously using a solution similar to the one described in this answer.
However, it seems that we are no longer able to do the following using Entity Framework 7:
DbContext.Entry(existingPhoneNumber).CurrentValues.SetValues();
Visual Studio complains that:
EntityEntry does not contain a definition for 'CurrentValues'
etc...
I presume this means that this has not (yet?) been implemented for EF Core 1.0? Apart from manually updating the properties, is there any other solution?
As you have noticed, this API is not implemented yet in EF Core. See this work item: https://github.com/aspnet/EntityFramework/issues/1200
I know this is an old question but I ran into this issue today, and it appears it still isn't implemented in EF Core. So I wrote an extension method to use in the meantime that will update any object's properties with the matching values of any other object.
public static class EFUpdateProperties
{
public static TOrig UpdateProperties<TOrig, TDTO>(this TOrig original, TDTO dto)
{
var origProps = typeof(TOrig).GetProperties();
var dtoProps = typeof(TDTO).GetProperties();
foreach(PropertyInfo dtoProp in dtoProps)
{
origProps
.Where(origProp => origProp.Name == dtoProp.Name)
.Single()
.SetMethod.Invoke(original, new Object[]
{
dtoProp.GetMethod.Invoke(dto, null) });
}
);
return original;
}
}
Usage:
public async Task UpdateEntity(EditViewModel editDto)
{
// Get entry from context
var entry = await _context.Items.Where(p => p.ID == editDto.Id).FirstOrDefaultAsync();
// Update properties
entry.UpdateProperties(editDto);
// Save Changes
await _context.SaveChangesAsync();
}

Entity Framework 6 RTM - Custom Relationship Convention

I was using a convention like this in the beta version of EF6:
public class NavigationPropertyConfigurationConvention : IConfigurationConvention<PropertyInfo, NavigationPropertyConfiguration>
{
public void Apply(PropertyInfo propertyInfo, Func<NavigationPropertyConfiguration> configuration)
{
var foreignKeyProperty = propertyInfo.DeclaringType.GetProperty("Id" + propertyInfo.Name);
if (foreignKeyProperty != null && configuration().Constraint == null)
{
var fkConstraint = new ForeignKeyConstraintConfiguration();
fkConstraint.AddColumn(foreignKeyProperty);
configuration().Constraint = fkConstraint;
}
}
}
But with the IConfigurationConvention interface has been marked as internal, I can't upgrade my EF's references. Have searched by many places, but not found how to reproduce that functionality in the RTM version.
I have also tried this, but seems only works with independent associations (IAs), what is not my case cause I have the FKs in CLR objects.
Has anyone done it works again?
Thanks!

Entity Framework 5 Generates SQL Referencing NotMapped Property

I just set about updating a project from Entity Framework 4.3.1 and .NET 4 to Entity Framework 5.0 and .NET 4.5. I updated the .NET version first, and ensured that I'm referencing EF 5.0.0.0 rather than the .NET 4 compatible 4.4.0.0.
I have a class structure like
public class MyBase
{
[NotMapped]
public bool MyProperty { get; set; }
}
public class MyDefinition : MyBase
{
// Some other properties
}
When I attempt to load some MyDefinition instances
using (MyContext ctx = new MyContext())
{
ctx.Configuration.AutoDetectChangesEnabled = false;
ctx.Configuration.LazyLoadingEnabled = false;
ctx.Configuration.ProxyCreationEnabled = false;
var defs = from def in ctx.MyDefinitions.AsNoTracking() select def;
foreach (MyDefinition def in defs) // <-- Exception here
{
// Do stuff
}
}
I get a SqlException
Invalid column name 'MyProperty'.
It is as if NotMapped is respected for purposes of determining whether the existing schema is valid, but the SELECT generated by EF 5 expects there to be a MyProperty column.
The base class and derived class are defined in different assemblies. Both assemblies were carefully checked to ensure they reference EF 5.0.0.0 and target .NET 4.5.
Intellisense claims that NotMapped is System.ComponentModel.DataAnnotations.Schema.NotMapped
How can I prevent EF 5 from selecting that non-existent column?
Add this
using System.ComponentModel.DataAnnotations.Schema
D'oh!
I also updated to VS 2012 today. Something unrelated broke with a post-build event, which caused an earlier version of the assembly containing the base class to be available to the derived class. Fixing the post build event resolved the issue.