Code First, set GetDate() on DateTime2 field - entity-framework-6

I've followed the examples like accepted here: Possible to default DateTime field to GETDATE() with Entity Framework Migrations?
In Sql server, the "Default Binding or Value" is now getting set to ('1900-01-01T00:00:00.000'), but not to GetDate() as I would expect.
public partial class InitialCreate : DbMigration
{
public override void Up()
{
AddColumn("dbo.UserWordsModels", "DateAdded", c => c.DateTime(defaultValueSql: "GETDATE()"));
}
public override void Down()
{
DropColumn("dbo.UserWordsModels", "DateAdded");
}
}
In the Model:
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime DateAdded { get; set; }
One thing I may have different is I set this so all DateTime fields are DateTime2
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Properties<DateTime>().Configure(c => c.HasColumnType("datetime2"));}

Related

Sql Exeption: Invalid column name "NormalizedUserName..." in existing .net framework identiy db used by .net core project

I have a projct in .Net Framework. i use .Net Framework and .Net Framework Asp.net Identity. There is no problem here...
Now I am creating a new project. It's a .Net Core 2.2 Project that must connect to the existing database. I cannot change the structure of the database. I have scaffolded the db withi this command
Scaffold-DbContext -Connection "..." -Provider Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Context MyDatabaseContext -Tables "Profile", <other_tables_no_identity>
So the database has been scaffolded, then I modified manually the following files
I have added IdentityUser to Profile entity
public partial class Profile : IdentityUser {...}
I have modified the OnModelCreating in this way:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//I have added this lines
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<IdentityUser>(entity =>
{
entity.ToTable("BaseProfile");
entity.Property(e => e.Id)
.HasMaxLength(128)
.ValueGeneratedNever();
entity.Property(e => e.Email)
.IsRequired()
.HasMaxLength(256);
entity.Property(e => e.UserName)
.IsRequired()
.HasMaxLength(256);
});
modelBuilder.Entity<Profile>(entity =>
{
entity.ToTable("Profile");
entity.HasIndex(e => e.Id)
.HasName("IX_Id");
entity.Property(e => e.Id)
.HasMaxLength(128)
.ValueGeneratedNever();
entity.Property(e => e.CreationDate).HasColumnType("datetime");
entity.Property(e => e.LastAccessDate).HasColumnType("datetime");
entity.Property(e => e.Rating).HasColumnType("decimal(18, 2)");
});
modelBuilder.Entity<IdentityUserRole<string>>().ToTable("ProfileRoleAssociation");
modelBuilder.Entity<IdentityUserLogin<string>>().ToTable("ProfileLoginAssociation");
modelBuilder.Entity<IdentityUserClaim<int>>().ToTable("ProfileClaimAssociation");
modelBuilder.Entity<IdentityRole>().ToTable("ProfileRole");
}
I have copied that lines from the old .Net Framework project... But when I try to make a login I obtain this error:
An unhandled exception occurred while processing the request.
SqlException: Invalid column name 'NormalizedUserName'.
Invalid column name 'AccessFailedCount'.
Invalid column name 'ConcurrencyStamp'.
Invalid column name 'Email'.
Invalid column name 'EmailConfirmed'.
Invalid column name 'LockoutEnabled'.
Invalid column name 'LockoutEnd'.
Invalid column name 'NormalizedEmail'.
Invalid column name 'NormalizedUserName'.
Invalid column name 'PasswordHash'.
Invalid column name 'PhoneNumber'.
Invalid column name 'PhoneNumberConfirmed'.
Invalid column name 'SecurityStamp'.
Invalid column name 'TwoFactorEnabled'.
Invalid column name 'UserName'.
The column name NormalizedUserName does not exists. But the others yes.
What's wrong? Thank you
EDIT
I understood the problem is about inheritance. It look for columns inside Profile table instead of BaseProfile... but I still do not understand how to solve it.
It has been a bit complicating, because of I could not modify the original .net framework application....
Here the situation in the old .net framework project:
I have a profile class inherits from IdentityUser.
public class Profile : IdentityUser { ... }
Then OnModelCreating I have this
var baseProfile = modelBuilder.Entity<IdentityUser>().ToTable("BaseProfile");
modelBuilder.Entity<Profile>().ToTable("Profile");
modelBuilder.Entity<IdentityUserRole>().ToTable("ProfileRoleAssociation");
modelBuilder.Entity<IdentityUserLogin>().ToTable("ProfileLoginAssociation");
modelBuilder.Entity<IdentityUserClaim>().ToTable("ProfileClaimAssociation");
modelBuilder.Entity<IdentityRole>().ToTable("ProfileRole");
So, that was the initial situation I could not change.
Well, In my new .net core project I have launche this command in the PackageManager Console:
Scaffold-DbContext -Connection {connection_string} -Provider Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Context MyContext -Tables "Profile", "BaseProfile", <other_tables>
Note BaseProfile is not an entity in the .net framework. And note that for some reason, the command does not generate the properties defined in the IdentityUser class. So, I have modified the auto-generated class as following:
public partial class BaseProfile : IdentityUser
{
public override string Id { get; set; }
public override string Email { get; set; }
public override bool EmailConfirmed { get; set; }
public override string PasswordHash { get; set; }
public override string SecurityStamp { get; set; }
public override string PhoneNumber { get; set; }
public override bool PhoneNumberConfirmed { get; set; }
public override bool TwoFactorEnabled { get; set; }
public DateTime? LockoutEndDateUtc { get; set; }
public override bool LockoutEnabled { get; set; }
public override int AccessFailedCount { get; set; }
public override string UserName { get; set; }
public override string NormalizedEmail { get { return this.Email.ToUpperInvariant(); } }
public override string NormalizedUserName { get { return this.UserName.ToUpperInvariant(); } }
public virtual Profile Profile { get; set; }
}
I have modified the BaseProfile so that it inherits from IdentityUser. All properties auto-generated by scaffolding command and defined in IdentityUser class have been overriden. Do not delete them, even if they are defined in IdentityUser would not be binded to the database.
I also created two new properties:
public override string NormalizedEmail { get { return this.Email.ToUpperInvariant(); } }
public override string NormalizedUserName { get { return this.UserName.ToUpperInvariant(); } }
Normalized* properties donot exist in old version of MS Identity. But they are necessary for the new one. That two properties need to let users to login. In fact the input of the user during login is compared with that two properties. Well, it is not the most correct the implementation of that properties. But for my culture is ok.
Finally, OnModelCreating I have added theese lines:
modelBuilder.Entity<BaseProfile>(entity =>
{
entity.ToTable("BaseProfile");
entity.Ignore(e => e.LockoutEnd);
entity.Ignore(e => e.ConcurrencyStamp);
entity.Ignore(e => e.NormalizedEmail);
entity.Ignore(e => e.NormalizedUserName);
entity.Ignore(e => e.LockoutEnd);
});
That are properties not in old version of Identity, but only in the new one.

Self-referencing table in EF6

I thought this was going to be easy... I have a situation where I have a table Module, which can contain "base" modules, and "compound" modules (that are made up from 1-n base modules).
So I have these two tables in SQL Server 2014:
CREATE TABLE Module
(
ModuleId INT NOT NULL IDENTITY(1,1)
CONSTRAINT PK_Module PRIMARY KEY CLUSTERED,
ModuleName VARCHAR(100)
)
CREATE TABLE CompoundModule
(
CompoundModuleId INT NOT NULL
CONSTRAINT FK_CompoundModule_MainModule
FOREIGN KEY REFERENCES dbo.Module(ModuleId),
BaseModuleId INT NOT NULL
CONSTRAINT FK_CompoundModule_BaseModules
FOREIGN KEY REFERENCES dbo.Module(ModuleId),
CONSTRAINT PK_CompoundModule
PRIMARY KEY CLUSTERED(CompoundModuleId, BaseModuleId)
)
and I filled in a few base modules:
INSERT INTO dbo.Module (ModuleName)
VALUES ('Base Module #1'), ('Base Module #2'), ('Base Module #3')
Now I created an EF 6 "code-first, reverse-engineer from database" model and get this Module class:
[Table("Module")]
public partial class Module
{
public Module()
{
Module1 = new HashSet<Module>();
Module2 = new HashSet<Module>();
}
public int ModuleId { get; set; }
public string ModuleName { get; set; }
public virtual ICollection<Module> Module1 { get; set; }
public virtual ICollection<Module> Module2 { get; set; }
}
and this context class:
public partial class ModuleCtx : DbContext
{
public ModuleCtx() : base("name=ModuleCtx")
{ }
public virtual DbSet<Module> Module { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Module>()
.Property(e => e.ModuleName)
.IsUnicode(false);
modelBuilder.Entity<Module>()
.HasMany(e => e.Module1)
.WithMany(e => e.Module2)
.Map(m => m.ToTable("CompoundModule").MapLeftKey("BaseModuleId").MapRightKey("CompoundModuleId"));
}
}
When I'm now trying to create a new compound module with this code, it turns out things aren't quite as easy as I thought.....
using (ModuleCtx ctx = new ModuleCtx())
{
Module newCompound = new Module();
Module baseModule1 = ctx.Module.FirstOrDefault(m => m.ModuleId == 1);
Module baseModule3 = ctx.Module.FirstOrDefault(m => m.ModuleId == 3);
newCompound.BaseModules.Add(baseModule1);
newCompound.BaseModules.Add(baseModule3);
ctx.Module.Add(newCompound);
ctx.SaveChanges();
}
This code causes an error (on the line trying to fetch the base module #1):
System.Data.Entity.Core.EntityCommandExecutionException was unhandled
HResult=-2146232004
Message=An error occurred while executing the command definition. See the inner exception for details.
Source=EntityFramework
InnerException: System.Data.SqlClient.SqlException
HResult=-2146232060
Message=Invalid column name 'Module_ModuleId'.
What am I missing here?? And why isn't the EF6 reverse-engineering code smart enough to create a model that works in this case??
I've been using EF4 with database-first approach so far, so all this fluent code-first configuration is still a bit of a mystery (and problem) to me...... does anyone see my (most likely very) obvious rookie mistake??
PS: this is the code that the "Code-first from existing database" reverse-engineering produces - not my own. So why does the reverse engineering output code that doesn't work in the end??
Try my generator EntityFramework Reverse POCO Generator and see if that does a better job for you.
It generated the following code (interesting stuff at the bottom):
public interface IMyDbContext : System.IDisposable
{
System.Data.Entity.DbSet<Module> Modules { get; set; } // Module
int SaveChanges();
System.Threading.Tasks.Task<int> SaveChangesAsync();
System.Threading.Tasks.Task<int> SaveChangesAsync(System.Threading.CancellationToken cancellationToken);
}
public class MyDbContext : System.Data.Entity.DbContext, IMyDbContext
{
public System.Data.Entity.DbSet<Module> Modules { get; set; } // Module
static MyDbContext()
{
System.Data.Entity.Database.SetInitializer<MyDbContext>(null);
}
public MyDbContext()
: base("Name=MyDbContext")
{
}
public MyDbContext(string connectionString)
: base(connectionString)
{
}
public MyDbContext(string connectionString, System.Data.Entity.Infrastructure.DbCompiledModel model)
: base(connectionString, model)
{
}
public MyDbContext(System.Data.Common.DbConnection existingConnection, bool contextOwnsConnection)
: base(existingConnection, contextOwnsConnection)
{
}
public MyDbContext(System.Data.Common.DbConnection existingConnection, System.Data.Entity.Infrastructure.DbCompiledModel model, bool contextOwnsConnection)
: base(existingConnection, model, contextOwnsConnection)
{
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
}
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Configurations.Add(new ModuleConfiguration());
}
public static System.Data.Entity.DbModelBuilder CreateModel(System.Data.Entity.DbModelBuilder modelBuilder, string schema)
{
modelBuilder.Configurations.Add(new ModuleConfiguration(schema));
return modelBuilder;
}
}
public class Module
{
public int ModuleId { get; set; } // ModuleId (Primary key)
public string ModuleName { get; set; } // ModuleName (length: 100)
// Reverse navigation
public virtual System.Collections.Generic.ICollection<Module> BaseModule { get; set; } // Many to many mapping
public virtual System.Collections.Generic.ICollection<Module> CompoundModule { get; set; } // Many to many mapping
public Module()
{
BaseModule = new System.Collections.Generic.List<Module>();
CompoundModule = new System.Collections.Generic.List<Module>();
}
}
// Module
public class ModuleConfiguration : System.Data.Entity.ModelConfiguration.EntityTypeConfiguration<Module>
{
public ModuleConfiguration()
: this("dbo")
{
}
public ModuleConfiguration(string schema)
{
ToTable("Module", schema);
HasKey(x => x.ModuleId);
Property(x => x.ModuleId).HasColumnName(#"ModuleId").IsRequired().HasColumnType("int").HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity);
Property(x => x.ModuleName).HasColumnName(#"ModuleName").IsOptional().IsUnicode(false).HasColumnType("varchar").HasMaxLength(100);
HasMany(t => t.CompoundModule).WithMany(t => t.BaseModule).Map(m =>
{
m.ToTable("CompoundModule", "dbo");
m.MapLeftKey("BaseModuleId");
m.MapRightKey("CompoundModuleId");
});
}
}

In Entity Framework 7 which property Attribute creates an index in code first?

In Entity Framework 7 (7.0.0-rc1-final) which property Attribute creates an index?
I would normally add an index to a sql table to improve look up times so I assume I need to specify this in my class?
public class Account
{
[Key]
[Required]
public int AccountId { get; set; }
[Required] <-- How do I make this an Index in Sql Server?
public int ApplicationUserId { get; set; }
}
I assume [Index] would do it but this is not recognised.
How do I index the ApplicationUserId column?
Use the fluent API in your DbContext class:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Account>()
.HasIndex(b => b.ApplicationUserId);
}
Here is a workaround:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class IndexAttribute : Attribute
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
foreach (var entity in modelBuilder.Model.GetEntityTypes())
{
foreach (var property in entity.GetProperties())
{
if (property.PropertyInfo != null && property.PropertyInfo.GetCustomAttributes<IndexAttribute>().Any())
{
entity.AddIndex(new[] { property });
}
}
}
}

ASP.NET MVC 5.0 model class - how to have a property in model class but not create a Database field

This question is in regards to ASP.NET MVC 5.0 model class.
I have a ASP.NET MVC5.0 model class for example that looks like this
public class Car
{
public int ID { get; set; }
public string CarType { get; set; }
public string SelectedType { get; set; }
}
However, I do not want a database field created for this model for property SelectedType.
Is there any attribute available to tell the Entity Framework not to create a database field for SelectedType?
Thank you for your help in advance.
you can use Fluent API ignore for example;
modelBuilder.Entity<Department>().Ignore(t => t.Budget);
You can use the NotMapped Data Annotation to exclude a purticular property like below:
public class Car
{
//
[NotMapped]
public string SelectedType { set; get; }
}
You also can do this with Fluent API, but you need to override the OnModelCreating like below:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Car>().Ignore(n => n.SelectedType );
base.OnModelCreating(modelBuilder);
}

Entity Framework - Code First not generating associated collections in the Database

I'm using CTP5 of the code first. Take the following simple class and associated DbContext
public class Test
{
public Test()
{
Keywords = new Collection<string>();
}
public int Id { get; set; }
public string Name { get; set; }
public ICollection<string> Keywords { get; set; }
}
public class TestDbContext : DbContext
{
public TestDbContext()
{
Database.Delete();
Database.CreateIfNotExists();
}
public DbSet<Test> Tests { get; set; }
protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
The type 'System.Collections.Generic.ICollection' must be a non-nullable value type in order to use it as parameter 'T'
in the generic type or method 'System.Data.Entity.ModelConfiguration.Configuration.Types.StructuralTypeConfiguration
.Property(System.Linq.Expressions.Expression>)'
Any ideas how to create the necessary table relationships between test class and the keywords property?
Add class Keyword and change ICollection<string> Keywords {get; set;} to ICollection<Keyword> Keywords {get; set;}
public class Keyword
{
public string Data {get;set;}
}
and code model creating like this:
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Keyword>()
.HasKey(x => x.Data);
base.OnModelCreating(builder);
}
Just imagine, that you have 2 collections 1 - Keywords, 2 - Tags. Your realization would map it to same table, because in ORM mapping type defines entity. And both Keyword and Tag are of type string. So to split this entities you should split types.

Resources