Imagine these models are a part of a social network application. User can make a Group and can add other users in it(as members) and a user can be a member of the group. I'm using .net core and also entity framework core.
Models:
public class User : BaseEntity
{
public string UserName { get; set; }
public IList<Group> OwnGroups { get; set; }
public IList<GroupMember> MemberInGroups { get; set; }
}
public class Group : BaseEntity
{
public string Name { get; set; }
public int OwnerUserId { get; set; }
[ForeignKey("OwnerUserId")]
public User OwnerUser { get; set; }
public IList<GroupMember> Members { get; set; }
}
public class GroupMember : BaseEntity
{
public int GroupId { get; set; }
public int UserId { get; set; }
[ForeignKey("UserId")]
public User User { get; set; }
[ForeignKey("UserId")]
public Group Group { get; set; }
}
Fluent API:
modelBuilder.Entity<User>()
.HasMany(x => x.OwnGroups)
.WithOne(x => x.OwnerUser).HasForeignKey(x => x.OwnerUserId).IsRequired().OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<User>()
.HasMany(x => x.MemberInGroups)
.WithOne(x => x.User).HasForeignKey(x => x.UserId).IsRequired().OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Group>()
.HasMany(x => x.Members)
.WithOne(x => x.Group).HasForeignKey(x => x.GroupId).IsRequired().OnDelete(DeleteBehavior.Cascade);
When I want to migrate to the database, this error happens:
Introducing FOREIGN KEY constraint 'FK_GroupMembers_Users_UserId' on table 'GroupMembers' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint or index. See previous errors.
However, I can make this model in SQL Server manually and there is no problem.
There are at least two ways to fix it. But I want to know why EF Core says, there is a cycle. What's the problem is?
I think your bridge table(junction) has a problem.
Try this
public class GroupMember: BaseEntity
{
public User User { get; set; }
[Key, Column(Order = 0)]
public int UserId { get; set; }
public Group Group { get; set; }
[Key, Column(Order = 1)]
public int GroupId { get; set; }
}
First of all: Get rid of the Fluent API part
//modelBuilder.Entity<User>()
//.HasMany(x => x.OwnGroups)
//.WithOne(x => x.OwnerUser).HasForeignKey(x => x.OwnerUserId).IsRequired().OnDelete(DeleteBehavior.Cascade);
//modelBuilder.Entity<User>()
// .HasMany(x => x.MemberInGroups)
// .WithOne(x => x.User).HasForeignKey(x => x.UserId).IsRequired().OnDelete(DeleteBehavior.Cascade);
//modelBuilder.Entity<Group>()
// .HasMany(x => x.Members)
// .WithOne(x => x.Group).HasForeignKey(x => x.GroupId).IsRequired().OnDelete(DeleteBehavior.Cascade);
And then, based on Microsoft Docs, choose one of these cases:
Change one or more of the relationships to not cascade delete(make it nullable)
public int? OwnerUserId { get; set; }
The second approach instead, we can keep the OwnerUserId relationship required(non-nullable) and configured for cascade delete, but make this configuration only apply to tracked entities, not the database.
modelBuilder
.Entity<User>()
.HasMany(e => e.OwnGroups)
.WithOne(e => e.OwnerUser)
.OnDelete(DeleteBehavior.ClientCascade);
In this way, if we want to delete a User and all its Groups, we should load both the User and its Groups in the application(RAM). Look at this:
After running this code, the User and all its Groups will be removed.
var context = new MyDbContext();
var user = context.Users.Single(x => x.UserName == "SampleName");
var groups = context.Groups.Where(x => x.OwnerUser == user).ToList();
context.Users.Remove(user);
context.SaveChanges();
But the code below will throw an exception.
var context = new MyDbContext();
var user = context.Users.Single(x => x.UserName == "SampleName");
context.Users.Remove(user);
context.SaveChanges();
Microsoft.Data.SqlClient.SqlException (0x80131904): Introducing FOREIGN KEY constraint 'FK_Groups_Users_OwnerUserId' on table 'Groups' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Related
I have the traditional ApplicationUser (IdentityUser), and that user can send a friend request to another ApplicationUser. I currently have the following general entity classes:
public class ApplicationUser : IdentityUser
{
public virtual List<DeviceToken> DeviceTokens { get; set; } = new List<DeviceToken>();
public string DisplayName { get; set; }
}
public class FriendRequest
{
public int Id { get; set; }
public DateTime DateRequested { get; set; }
public ApplicationUser Requester { get; set; }
public ApplicationUser Receiver { get; set; }
}
I have ran database-update etc and this is working fine. However when I go into my SQLServer to try to delete an ApplicationUser, it tells me that The DELETE statement conflicted with the REFERENCE constraint "FK_FriendRequest_AspNetUsers_RequesterId".
So I have decided to implement a cascade delete flow from the ApplicationUser to the friend requests that they are part of.
I have tried the resource on here by Microsoft on configuring cascade delete but I cannot figure out how to apply it to my case:
builder.Entity<ApplicationUser>()
.HasMany(e => e.FriendRequests)//No such property, no idea how to address
.OnDelete(DeleteBehavior.ClientCascade);
How do I set up this cascade delete scenario?
Also how do I add a property to ApplicationUser that refers to all the FriendRequests they are part of, and make sure EFCore knows I am referring to that existing FriendRequest entity/table?
Update
Following the suggested approach of adding a virtual property to ApplicationUser, would this be way forward:
public class ApplicationUser : IdentityUser
{
public virtual List<DeviceToken> DeviceTokens { get; set; } = new List<DeviceToken>();
public string DisplayName { get; set; }
public ICollection<FriendRequest> FriendRequests { get; }
}
builder.Entity<ApplicationUser>()
.HasMany(u => u.FriendRequests)
.WithOne(u => u.Requester)
.OnDelete(DeleteBehavior.ClientCascade); //not sure about this
builder.Entity<ApplicationUser>()
.HasMany(u => u.FriendRequests)
.WithOne(u => u.Requester)
.OnDelete(DeleteBehavior.ClientCascade); //not sure about this
Your ApplicationUser needs 2 virtual ICollections.
public class ApplicationUser
{
public int Id { get; set; }
public string DisplayName { get; set; }
public virtual ICollection<FriendRequest> FriendRequestsAsRequestor { get; set; }
public virtual ICollection<FriendRequest> FriendRequestsAsReceiver { get; set; }
}
public class FriendRequest
{
public int Id { get; set; }
public DateTime DateRequested { get; set; }
public int RequestorId { get; set; }
public ApplicationUser Requestor { get; set; }
public int ReceiverId { get; set; }
public ApplicationUser Receiver { get; set; }
}
public class ApplicationUserConfig : IEntityTypeConfiguration<ApplicationUser>
{
public void Configure(EntityTypeBuilder<ApplicationUser> builder)
{
builder.HasMany(au => au.FriendRequestsAsRequestor)
.WithOne(fr => fr.Requestor)
.HasForeignKey(fr => fr.RequestorId)
.OnDelete(DeleteBehavior.Cascade);
builder.HasMany(au => au.FriendRequestsAsReceiver)
.WithOne(fr => fr.Receiver)
.HasForeignKey(fr => fr.ReceiverId)
.OnDelete(DeleteBehavior.Cascade);
}
}
Use:
void AddFriendRequest(int requestorId, int receiverId)
{
var ctxt = new DbContext();
FriendRequest fr = new FriendRequest
{
RequestorId = requestorId;
ReceiverId = receiverId;
DateRequested = DateTime.Now;
}
ctxt.FriendRequests.Add(fr);
ctxt.SaveChanges();
}
List<FriendRequest> GetFriendRequests()
{
var ctxt = new DbContext();
return ctxt.FriendRequests
.Include(fr => fr.Requestor)
.Include(fr => fr.Receiver)
.ToList();
}
ApplicationUser GetUserWithFriendRequests(int id)
{
var ctxt = new DbContext();
return ctxt.ApplicationUser
.Include(au => au.FriendRequestsAsRequestor)
.Include(au => au.FriendRequestsAsReceiver)
.SingleOrDefault(au => au.Id == id);
}
I have tried the resource on here by Microsoft on configuring cascade delete but I cannot figure out how to apply it to my case:
builder.Entity<ApplicationUser>()
.HasMany(e => e.FriendRequests)//No such property, no idea how to address
.OnDelete(DeleteBehavior.ClientCascade);
From the doc of DeleteBehavior :
ClientCascade : For entities being tracked by the DbContext, dependent entities will be deleted when the related principal is deleted. If the database has been created from the model using Entity Framework Migrations or the EnsureCreated() method, then the behavior in the database is to generate an error if a foreign key constraint is violated.
In this case, it's the client (the .NET app) and not the DB that ensure the cascade delete. If the client fail to do the cascade delete (related entity not tracked), the db will generate the error you see.
Maybe the DeleteBehavior.Cascade is more appropriate to your code first scenario :
Cascade : For entities being tracked by the DbContext, dependent entities will be deleted when the related principal is deleted. If the database has been created from the model using Entity Framework Migrations or the EnsureCreated() method, then the behavior in the database is the same as is described above for tracked entities. Keep in mind that some databases cannot easily support this behavior, especially if there are cycles in relationships, in which case it may be better to use ClientCascade which will allow EF to perform cascade deletes on loaded entities even if the database does not support this. This is the default for required relationships. That is, for relationships that have non-nullable foreign keys.
If you try this, you go with this SQL script migration (I assume the SGBDR is SQL Server) :
CREATE TABLE [ApplicationUser] (
[Id] int NOT NULL IDENTITY,
[DisplayName] nvarchar(max) NULL,
CONSTRAINT [PK_ApplicationUser] PRIMARY KEY ([Id])
);
GO
CREATE TABLE [FriendRequests] (
[Id] int NOT NULL IDENTITY,
[DateRequested] datetime2 NOT NULL,
[RequesterId] int NULL,
[ReceiverId] int NULL,
CONSTRAINT [PK_FriendRequests] PRIMARY KEY ([Id]),
CONSTRAINT [FK_FriendRequests_ApplicationUser_ReceiverId] FOREIGN KEY ([ReceiverId]) REFERENCES [ApplicationUser] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_FriendRequests_ApplicationUser_RequesterId] FOREIGN KEY ([RequesterId]) REFERENCES [ApplicationUser] ([Id]) ON DELETE CASCADE
);
GO
And when it's apply, this produce this error :
Introducing FOREIGN KEY constraint 'FK_FriendRequests_ApplicationUser_RequesterId' on table 'FriendRequests' may cause cycles or multiple cascade paths.
Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
First time I see this error, then I will refer to this question with #onedaywhen's answer :
SQL Server does simple counting of cascade paths and, rather than trying to work out whether any cycles actually exist, it assumes the worst and refuses to create the referential actions (CASCADE)...
A no perfect solution is to use DeleteBehavior.Cascade and ensure all related entities are tracked before the delete :
public class ApplicationUser
{
public int Id { get; set; }
public string DisplayName { get; set; }
public ICollection<FriendRequest> RequestedRequests { get; set; }
public ICollection<FriendRequest> RecevedRequests { get; set; }
}
public class FriendRequest
{
public int Id { get; set; }
public DateTime DateRequested { get; set; }
public ApplicationUser Requester { get; set; }
public ApplicationUser Receiver { get; set; }
}
public class MyDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
optionsBuilder.UseSqlServer("***");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<FriendRequest>()
.HasOne(r => r.Requester)
.WithMany(u => u.RequestedRequests)
.OnDelete(DeleteBehavior.ClientCascade);
modelBuilder.Entity<FriendRequest>()
.HasOne(r => r.Receiver)
.WithMany(u => u.RecevedRequests)
.OnDelete(DeleteBehavior.ClientCascade);
}
public DbSet<ApplicationUser> Users { get; set; }
public DbSet<FriendRequest> FriendRequests { get; set; }
public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default)
{
PrepareUserToDeleting();
return base.SaveChangesAsync();
}
public override int SaveChanges(bool acceptAllChangesOnSuccess)
{
PrepareUserToDeleting();
return base.SaveChanges();
}
private void PrepareUserToDeleting()
{
// For each deleted user entity
foreach(var entry in ChangeTracker.Entries<ApplicationUser>().Where(e => e.State == EntityState.Deleted))
{
var user = entry.Entity;
// If RecevedRequests isn't loaded
if (user.RecevedRequests == null)
{
//Then load RecevedRequests
entry.Collection(u => u.RecevedRequests).Load();
}
// Idem with RequestedRequests
if (user.RequestedRequests == null)
{
entry.Collection(u => u.RequestedRequests).Load();
}
}
}
}
This is the simplified version of the table structure I have:
[Table("PolicyMapping")]
public class PolicyMapping
{
[Key]
public Guid Id { get; set; }
public Policy PolicyA { get; set; }
public Policy PolicyB { get; set; }
public Lookup_Bank Bank { get; set; }
}
[Table("Policy")]
public class Policy
{
[Key]
public Guid Id { get; set; }
public string PolicyNm { get; set; }
public string Description { get; set; }
}
[Table("Lookup_Bank")]
public class Lookup_Bank
{
[Key]
public Guid Id { get; set; }
public string Name { get; set; }
public string Code { get; set; }
}
I am working on the edit screen for policy mapping where you can have the same values for PolicyA and PolicyB attributes.
After using automapper for DTO to the entity, here is my entity object looks like:
var policyMapping = new PolicyMapping
{
Id = "b27fb632-330b-46be-a649-2e2463d58626",
PolicyA = new Policy
{
Id = "a4f1cf6f-034d-4727-ab8f-49e95b2c9d23",
PolicyNm = null,
Description = null
},
PolicyB = new Policy
{
Id = "a4f1cf6f-034d-4727-ab8f-49e95b2c9d23",
PolicyNm = null,
Description = null
},
Bank = new Lookup_Bank()
{
Id = "98ed2bae-631b-490c-8ddf-3e02232d4231",
Name = null,
Code = null
}
}
I am mapping only selected id value of dropdown to entity id using automapper. Values are present for Code, Description and other attributes in the database. It's just not getting populated after automapper.
dbContext.PolicyMapping.Attach(policyMapping);
dbContext.SaveChanges();
This is the error, I am getting
The instance of entity type Policy cannot be tracked because another instance with the same key value for {'a4f1cf6f-034d-4727-ab8f-49e95b2c9d23'} is already being tracked.
When attaching existing entities, ensure that only one entity instance with a given key value is attached.
The reason for the error maybe because I am attaching two different entities with the same Id. I am still not sure how can I make it work in the most efficient way?
Solution 1: (not efficient)
var fromdatabase = dbContext.PolicyMapping.Include(x => x.PolicyA)
.Include(x => x.Bank)
.Include(x => x.PolicyB)
.FirstOrDefault(x => x.Id == policyMapping.Id);
fromdatabase.PolicyA = dbContext.Policy.FirstOrDefault(x => x.Id == policyMapping.PolicyA.Id);
fromdatabase.PolicyB = dbContext.Policy.FirstOrDefault(x => x.Id == policyMapping.PolicyB.Id);
dbContext.PolicyMapping.Attach(fromdatabase);
dbContext.SaveChanges();
This is working. But I would like to avoid a trip to the database just to fetch the entire entity.
Edit: Based on Xing's answer
#Xing, pointed out to change the Model structure by adding navigational properties and some changes in OnModelCreating method. (This method is currently blank in my code)
However, I went through a couple of articles (This & This) related to EF Core Code First approach, none of them are saying about navigational properties and all.
I am wondering how they are updating the column in this scenario?
If you just would like to update the Id of the navigation properties, you could add foreign key for them and update it.
1.Model:
public class PolicyMapping
{
[Key]
public Guid Id { get; set; }
public Guid PolicyAId { get; set; }
public Policy PolicyA { get; set; }
public Guid PolicyBId { get; set; }
public Policy PolicyB { get; set; }
public Guid BankId { get; set; }
public Lookup_Bank Bank { get; set; }
}
2.DbContext:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<PolicyMapping>()
.HasOne(x => x.PolicyA)
.WithOne()
.HasForeignKey<PolicyMapping>(p => p.PolicyAId)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<PolicyMapping>()
.HasOne(x => x.PolicyB)
.WithOne()
.HasForeignKey<PolicyMapping>(p => p.PolicyBId)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<PolicyMapping>()
.HasOne(x => x.Bank)
.WithOne()
.HasForeignKey<PolicyMapping>(p => p.BankId)
.OnDelete(DeleteBehavior.Restrict);
}
3.Add migrations.
4.Controller:
var policyMapping = new PolicyMapping
{
Id = new Guid("b27fb632-330b-46be-a649-2e2463d58626"),
PolicyAId = new Guid("a4f1cf6f-034d-4727-ab8f-49e95b2c9d23"),
PolicyBId = new Guid("a4f1cf6f-034d-4727-ab8f-49e95b2c9d23"),
BankId = new Guid("98ed2bae-631b-490c-8ddf-3e02232d4231")
};
dbContext.PolicyMapping.Attach(policyMapping);
dbContext.Entry(policyMapping).Property("PolicyAId").IsModified = true;
dbContext.Entry(policyMapping).Property("PolicyBId").IsModified = true;
dbContext.Entry(policyMapping).Property("BankId").IsModified = true;
dbContext.SaveChanges();
Then you could retrieve PolicyA or PolicyB from their foreign key PolicyAId or PolicyBId
var policyA = dbContext.Policy.FirstOrDefault(x => x.Id == policyMapping.PolicyAId);
I'm using Entity Framework Core to create my (code first) database model.
In the model I have these classes:
[Table("groups")]
public class Group {
public int? Id { get; set; }
[JsonIgnore]
public virtual ICollection<Membership> Members { get; set; }
}
[Table("identities")]
public class Identity {
public int? Id { get; set; }
[JsonIgnore]
public virtual ICollection<Membership> MemberOf { get; set; }
}
[Table("memberships")]
public partial class Membership {
[Column("group_id")]
public int GroupId { get; set; }
[Column("identity_id")]
public int IdentityId { get; set; }
[JsonIgnore]
public virtual Group Group { get; set; }
[JsonIgnore]
public virtual Identity Identity{ get; set; }
}
Membership is a many-to-many relationship between Group and Identity.
I have configured the relationship using the fluent API like this:
protected override void OnModelCreating(ModelBuilder modelBuilder) {
var entity = modelBuilder.Entity<Membership>();
entity.HasKey(e => new {
e.GroupId,
e.IdentityId }
).HasName("PK_identity_memberships");
entity.HasOne(d => d.Group)
.WithMany(p => p.Members)
.HasForeignKey(d => d.GroupId)
.HasConstraintName("memberships_group_id_fkey");
entity.HasOne(d => d.Identity)
.WithMany(p => p.MemberOf)
.HasForeignKey(d => d.IdentityId)
.HasConstraintName("memberships_identity_id_fkey");
}
My problem is that if I try to insert a Membership in the DB setting GroupId and IdentityId with valid values, I get this error:
Npgsql.PostgresException: 23503: insert or update on table "memberships" violates foreign key constraint "memberships_group_id_fkey"
To insert a Membership object, I need to set the Group and Identity navigation properties, and then everything works fine.
Is there a way to insert new objects without using the navigation properties?
I've finally found the problem. To reproduce (at least with NpgSql):
using (var db = new TestContext()) {
// This works:
db.Groups.Add(new Group {
Id = 42,
});
db.Identities.Add(new Identity {
Id = 666,
});
db.SaveChanges();
db.Memberships.Add(new Membership {
GroupId = 42,
IdentityId = 666
});
db.SaveChanges();
// this explodes...
db.Groups.Add(new Group {
Id = 0,
});
db.Identities.Add(new Identity {
Id = 0,
});
db.SaveChanges();
db.Memberships.Add(new Membership {
GroupId = 0,
IdentityId = 0
});
db.SaveChanges(); // exception here!
}
So, the problem was that I was using 0 as an ID for the objects I had created.
Using a non-zero integer, even negative, seems to work instead.
This might be a bug in NpgSql, I suppose, since 0 seems to be a valid value for an ID (since I can insert records manually in the DB).
Some of the entities in my application have 4 audit properties on them:
public virtual DateTime WhenAdded { get; set; }
public virtual DateTime? WhenUpdated { get; set; }
public virtual User AddedBy { get; set; }
public virtual User UpdatedBy { get; set; }
I am using a code first approach and have the following extension method to map the user properties:
public static void MapAuditFields<T>(this EntityTypeConfiguration<T> configuration) where T : class, IAuditable
{
configuration.HasOptional<User>(e => e.AddedBy)
.WithOptionalDependent()
.Map(a => a.MapKey("AddedByUserId"));
configuration.HasOptional<User>(e => e.UpdatedBy)
.WithOptionalDependent()
.Map(a => a.MapKey("UpdatedByUserId"));
}
This is working fine in most cases, but not on the User class, which of course has a recursive relationship with itself. I have seen various posts on the internet suggesting that entity framework has a bug when you try to customise join table column names in this scenario, for example:
Self-referencing many-to-many recursive relationship code first Entity Framework
and
http://social.msdn.microsoft.com/Forums/en-US/f058097d-a0e7-4393-98ef-3b13ab5b165d/code-first-sequence-contains-more-than-one-matching-element-exception-when-generating-schema?forum=adonetefx
The error I am getting is "Sequence contains more than one matching element".
Does anyone know if this has been fixed in entity framework 6?
Many thanks.
Use WithMany() instead of WithOptionalDependent() as a user can add or update multiple other users
Class:
public class User
{
public int Id { get; set; }
public virtual User AddedBy { get; set; }
public virtual User UpdatedBy { get; set; }
}
Fluent API calls:
modelBuilder.Entity<User>()
.HasOptional( u => u.AddedBy )
.WithMany()
.Map( fkamc => fkamc.MapKey( "AddedByUserId" ) );
modelBuilder.Entity<User>()
.HasOptional( u => u.UpdatedBy )
.WithMany()
.Map( fkamc => fkamc.MapKey( "UpdatedByUserId" ) );
Results:
I am trying to split a legacy user table into two entities using a one to one mapping but keep getting migration errors stating that my database is out of sync, even though everything (i think is mapped) and i am trying to make a one-to-one relationship.
This is an existing database (although i am using code first as migrations will become important down the line) but i have not added any changes to the database (although i am unsure what exactly the one-to-one table split expects), i keep getting this:
The model backing the 'Context' context has changed since the database was created. Consider using Code First Migrations to update the database
I can update the database (either manually or via Migrations) but have no idea what is actually out of sync as no new fields have been added and the names match up.
BaseEntity:
public abstract class BaseEntity<T>
{
[Key]
public T Id { get; set; }
public DateTime CreatedOn { get; set; }
}
Membership Model:
public class Membership : BaseEntity<Guid>
{
public string UserName { get; set; }
public bool Approved { get; set; }
public bool Locked { get; set; }
public Profile Profile { get; set; }
}
Profile Model:
public class Profile : BaseEntity<Guid>
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string Telephone { get; set; }
public string Extension { get; set; }
public Membership Membership { get; set; }
}
Membership Mapping (this has the 1 to 1 Definition):
public class MembershipMap : EntityTypeConfiguration<Membership>
{
public MembershipMap()
{
//Primary Key
this.HasKey(t => t.Id);
//**Relationship Mappings
this.HasRequired(m => m.Profile)
.WithRequiredPrincipal(p => p.Membership);
//Properties & Column mapping
this.Property(m => m.Id)
.HasColumnName("PKID")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
this.Property(m => m.UserName)
.HasColumnName("Username")
.HasMaxLength(255);
this.Property(m => m.Approved)
.HasColumnName("IsApproved");
this.Property(m => m.Locked)
.HasColumnName("IsLocked");
this.Property(m => m.CreatedOn)
.HasColumnName("CreationDate");
this.ToTable("AppUser");
}
}
Profile Mapping:
public class ProfileMap : EntityTypeConfiguration<Profile>
{
public ProfileMap()
{
//Primary Key
this.HasKey(t => t.Id);
//Properties & Column mapping
this.Property(m => m.Id)
.HasColumnName("PKID")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
this.Property(m => m.FirstName)
.HasColumnName("FirstName");
this.Property(m => m.LastName)
.HasColumnName("LastName");
this.Property(m => m.Email)
.HasColumnName("Email");
this.Property(m => m.Telephone)
.HasColumnName("Telephone");
this.Property(m => m.Extension)
.HasColumnName("Extension");
this.ToTable("AppUser");
}
}
Database Table
I know that not all fields are mapped, but i do not need them at this stage, surely that wouldn't be the issue would it?
Issue was not Code First Mappings but caused by me switching databases and some rouge migrations coming into play.
To reset migrations you can see the answer here from a follow up question:
Resetting Context for Entity Framework 5 so it thinks its working with a initialised Database - Code First
Kudos to EvilBHonda