Entity Framework 5 Generates SQL Referencing NotMapped Property - entity-framework

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.

Related

Cannot update identity column "PartyID"

I upgraded project .net core sdk 2.2 to .net core sdk 3.1. My project is working well with .net core sdk 2.2. Party class exist in my project, I get that "Cannot update identity column "PartyID"" when I try to update party name. PartyID is primary key and increment by one by in sql table. Have you any idea?
public class Parties
{
public Parties()
{
}
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public int PartyID { get; set; }
}
Also, I researched this error on web and I added below code.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var partiesBuilder = modelBuilder.Entity<Parties>();
partiesBuilder.Property(p => p.PartyID).Metadata.SetAfterSaveBehavior(PropertySaveBehavior.Ignore);
partiesBuilder.Property(p => p.PartyID).UseSqlServerIdentityColumn();
partiesBuilder.Property(p => p.PartyID).ValueGeneratedOnAdd();
}
However I get this error :
"System.InvalidOperationException: 'The property 'PartyID' on entity type 'Parties' must be marked as read-only after it has been saved because it is part of a key. Key properties are always read-only once an entity has been saved for the first time.'".
Also I used this package:
EntityFramework version 6.4.4, Microsoft.EntityFrameworkCore version 3.1.6

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());
}
}
}

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();
}

how to use mvc-mini-profiler for database-first entity framework?

I am trying to use mvc-mini-profiler for db-first EF, but it is not working properly.
(note that I'm using objectcontext, not dbcontext)
Here is the list of stackoverflows I've tried:
Setup of mvc-mini-profiler for EF-db- first
How to get MVC-mini-profiler working on EF 4.1 Database First
versions:
Entity Framework: 4.3.1
MiniProfiler: 2.0.2
MiniProfiler.ef: 2.0.3
This is how I setup miniprofiler:
I've added the following stuff in Global.asax
protected void Application_BeginRequest(
{
MiniProfiler.Start();
}
protected void Application_EndRequest()
{
MiniProfiler.Stop();
}
protected void Application_Start()
{
...
MiniProfilerEF.Initialize_EF42();
}
Then configure an objectcontext,
var entityConnection = new EntityConnection(ConnectionString);
var profiledDbConnection = new EFProfiledDbConnection(entityConnection, MiniProfiler.Current);
var context = profiledDbConnection.CreateObjectContext<MyContext>();
var list = context.MyEntities.ToList();
If I execute this, the following exception occurs when running "context.MyEntities.ToList()"
[System.Data.EntityCommandCompliationException]
the message in the inner exception says:
EntityClient cannot be used to create a command definition from a store command tree.
Have I configured wrong? Any help?
thanks,
I use MiniProfiler and database first Entity Framework and it does work well. You may need to turn off the database initialization strategy inside of your database context as per this related answer: https://stackoverflow.com/a/9762989/325727
public class EmployeeContext : DbContext
{
static EmployeeContext() { Database.SetInitializer<EmployeeContext>(null); }
public IDbSet<Employee> Employees { get; set; }
}
The parameter null turns off database initialization by making sure that there is no initializer available.

WCF with Entity Framework Error

Error: The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
I am trying to create a WCF service with Entity Framework (VS 2010, .NET 4). When I run it, I get the above error.
I read something about editing the T4 template, but it appears that it already has
[DataContractAttribute(IsReference=true)]
public partial class Person : EntityObject
and
[DataMemberAttribute()]
public global::System.Int32 ID
{
get
{
return _ID;
}
I am not sure what the difference is between
[DataMemberAttribute()] and [DataMember]
or
[DataContractAttribute(IsReference=true)] and [DataContract]
either.
public Person GetPersonByID(int id)
{
using (var ctx = new MyEntities())
{
return (from p in ctx.Person
where p.ID == id
select p).FirstOrDefault();
}
}
How does WCF and EF work together, properly?
Do you have navigation properties in your Person class? Did you disable lazy loading? Otherwise it will probably try to load content for navigation properties during serialization and it fails because of closed context.
To your other questions:
[DataMemberAttribute()] and [DataMember] are same. It is just shorter name.
[DataContractAttribute(IsReference=true)] and [DataContract] are not same. IsRefrence allows tracking circular references in navigation properties. Without this parameter circular reference causes never ending recursion.