Set all an entity fields to required using fluent api - ef-code-first

Is there any way to set all an entity fields required at once using fluent API.

Try this approach:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Properties().Where(p => p.DeclaringType == typeof(EntityClassName))
.Configure(c => c.IsRequired());
}

Related

No suitable constructor found for entity type 'Uri'.

I have this model:
public class Book
{
public int Id { get; set; }
public string Name { get; set; }
public Uri Link { get; set; }
}
I added it to fluent-api using the following code:
builder.Entity<Book>(entity => {
entity.HasKey(b => b.Id);
});
when I run this:
add-migration InitialMigration -context MyAppContext
then I get:
No suitable constructor found for entity type 'Uri'. The following parameters could not be bound to properties of the entity: 'uriString', 'uriString', 'dontEscape', 'baseUri', 'relativeUri', 'dontEscape', 'uriString', 'uriKind', 'baseUri', 'relativeUri', 'serializationInfo', 'streamingContext', 'baseUri', 'relativeUri', 'flags', 'uriParser', 'uri'.
You can't persist a Uri directly to the database, as there's no associated SQL type for that. You need to use a string instead. If you're using a view model (as you should be), your view model can have the Uri, and then you simply need to get the string representation during your mapping to your actual entity type.
You can also simply utilize EF Core's value conversion (available in 2.1+). See the docs for more detail. Essentially, in your fluent config:
.HasConversion(
v => v.ToString(),
v => new Uri(v));
A value conversion can be added to your DbContext to convert the type used when reading from or writing to the database. This is done by overriding the OnModelCreating method.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<Book>()
.Property(e => e.Link)
.HasConversion(v => v.ToString(), v => new Uri(v));
}

Auto-increment IDs after importing data in the Entity Framework

I'm developing a new version of an old application using Entity Framework 6 Code First and ASP.NET with SQL Server 2014 as the back end. The old database is an Access database and has about a dozen tables with auto-increment IDs. I want to import the old data while keeping the IDs intact so that the relationships between the tables is preserved. I've set the key attribute on the new entities to
DatabaseGeneratedOption.None
This works, and I'm able to import all of the values from the old database, however I'd like to have the primary keys auto-increment from this point on. Since the DatabaseGeneratedOption is set to None it seems that I have to manually generate IDs in
You probably want to set the keys as identity as they were and then disable the identity-constraint during import.
You do this with SET IDENTITY_INSERT tablename ON before the insert statement. Dont forget to set it to OFF when you are done.
I never tried this, but you can have different configurations and switch them as per requirement/environment, hope this helps
public class IdentityDbConfiguration : EntityTypeConfiguration<Foo>
{
public IdentityDbConfiguration()
{
Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
}
public class DbConfiguration : EntityTypeConfiguration<Foo>
{
public DbConfiguration()
{
Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
}
}
public class AppContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new IdentityDbConfiguration());
}
}
public class AppContext2 : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new DbConfiguration());
}
}

How can I avoid ASP.NET Identity from adding this extra field?

I have a new MVC5 project with ASP.NET Identity 2.0 and EF 6.1.1.
I added my own ApplicationUser (based on built-in IdentityUser). This is how my DbContext is created.
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
When the database is created I have tables like AspNetUsers, AspNetUserRoles, AspNetUserClaims, and AspNetUserLogins. Then I added OnModelCreating() with just the most basic statements.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<IdentityUserLogin>().HasKey<string>(l => l.UserId);
modelBuilder.Entity<IdentityUserRole>().HasKey(r => new { r.RoleId, r.UserId });
}
As soon as I add OnModelCreating(), the identity tables are automatically renamed to ApplicationUsers, IdentityUserRoles, IdentityUserClaims, and IdentityUserLogins. That's fine with me (and I know how to rename them).
But what I don't like: All of a sudden, IdentityUserRoles, IdentityUserClaims, and IdentityUserLogins have an extra field called "ApplicationUser_Id". The original "AspNetXXX" tables didn't have such a field.
Why is that? And is there anything I can do in order to avoid this?
You need to call base.OnModelCreating. There are a number of additional things OnModelCreating does in IdentityDbContext that you may be missing without calling it - the default names of the tables being one of them.
Its best to call it first, then apply your own changes afterwards.
As mentioned by Matt Lassam-Jones
worked for me also and Thank You.
public class NebulaContext : IdentityDbContext<ApplicationUser>
{
public NebulaContext()
: base("Name=MyEntity", throwIfV1Schema: false)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); //Optional
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();//Optional
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); //Optional
base.OnModelCreating(modelBuilder);
}
}

Model change detection ASP.NET code first migrations

I have added
public IEnumerable<Comment> Comments { get; set; }
to a Model in an ASP.net MVC project. I ran the following to generate a migration in the package console
PM> Add-Migration AddCommentsToDevice
and the resulting migration did not pick up the change to the model
public partial class AddCommentsToDevice : DbMigration
{
public override void Up()
{
}
public override void Down()
{
}
}
Any tips on the syntax of the migrations or what causes detections?
You've added to little. You need to configure the relationship properly - the best with fluent api. Use this for navigation property:
public virtual ICollection<Comment> Comments { get; set; }
Important - always use ICollection, not IEnumerable for Navigation properties and make them virtual - thanks to this ef will be able to track changes.
Then in your DbContext you add following code:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Model>().HasKey(x => x.Id);
modelBuilder.Entity<Model>().HasMany(x => x.Comments);
base.OnModelCreating(modelBuilder);
}
I assumed that class related to Comments is named Model.

EFT CTP5 Disable Identity column on insert

I have an existing database that I would like to migrate to EF CTP5. The problem I have is that when I insert the existing data I need it to move retaining the current identity primary key for the other foreign key constraints.
I would like to migrate this using EF CTP5 code so I dont have to write lots of SQL or even contain it within an SSIS Package.
I have attempted to use the sql syntax:
SET IDENTITY_INSERT tableName ON
SET IDENTITY_INSERT tableName OFF
However, when DbContext.SaveChanges() is called the above syntax is happening in a different connection and the identity column is controlled by the EF CTP5 framework, even when specifying the ID.
Is there a way of disabling, or removing the identity convention to an object similar to the following, but on the fly rather than when the database is instantiated:
public class BlogContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<StoreGeneratedIdentityKeyConvention>();
}
}
Thanks
You can add the Identity setting on a field like so:
In your OnModelCreating in your DbContext class:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<ClassNameOfYourPOCO>().Property(p => p.IDFIELDNAME)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
You can remove it like so:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<ClassNameOfYourPOCO>().Property(p => p.IDFIELDNAME)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
}

Resources