MVC update model with Code-Migrations - asp.net-mvc

I am making my project in MVC4, where i am using my Code first approach. i need to update my model
i have a following property which needs to be update , how can i achieve this
public class ContactForm
{
public char Phone { get; set; }
}
public class ConContext : DbContext
{
public DbSet<ContactForm> ContactForms { get; set; }
}
}
i want to update Phone propery to
public char Phone { get; set; }
thnx in advance, i have installed migrations to my projet already
My configuration.cs
namespace MyCRM.Migrations
{
using System;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;
internal sealed class Configuration : DbMigrationsConfiguration<MyCRM.Models.ConContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(MyCRM.Models.ConContext context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data. E.g.
//
// context.People.AddOrUpdate(
// p => p.FullName,
// new Person { FullName = "Andrew Peters" },
// new Person { FullName = "Brice Lambson" },
// new Person { FullName = "Rowan Miller" }
// );
//
}
}
}

The normal flow with EF code-first is too first update the model (a C# file) :
public class ContactForm
{
public string Phone { get; set; } //previously, this was let's say of type int
}
Then, you build your project and after that in the Package Manager Console, you have to call Add-Migration with some label (in order to rollback changes later if needed) :
Add-Migration Phone
This will add to your solution a file named like this 201409xxxxxxxx_Phone under the directory Migrations.
Then you have to put the changes to your database which can be done with the command (always in the console) :
Update-Database
Then, you should be done : the property Phone is of type string everywhere.

Related

EF Core empty migration issue

I am using .Net Core 2.1 and EF Core 2.1. I successfully created 2 tables with EF Code First Migrations and dotnet CLI also seeded data into it. However when I try to add a new model Feature, and run the migration, the file generated has empty Up() and Down() methods and there is no entry in the EF_MigrationsHistory table of Database and the modelSnapshot.cs file also doesn't contain any references to the Feature model. I cross checked the ApplicationDbContext to see if I accidentally missed the declaration of the model in the class but I hadn't. I am not sure of the issue. Can anyone help me out with this? Posting the codes from my project:
Feature.cs
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace ProjectName.Models
{
public class Feature
{
public int Id { get; set; }
[Required]
[StringLength(255)]
public string Name { get; set; }
}
}
ApplicationDbContext.cs
using Microsoft.EntityFrameworkCore;
using ProjectName.Models;
namespace ProjectName.Persitance{
public class ApplicationDbContext: DbContext{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> context)
: base(context){ }
public DbSet<Make> Makes { get; set; }
public DbSet<Feature> Features { get; set; }
}
}
20180906063933_AddFeature.cs(Migration File):
using Microsoft.EntityFrameworkCore.Migrations;
namespace ProjectName.Migrations
{
public partial class AddFeature : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
}
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}
ApplicationDbContextModelSnapshot.cs:
// <auto-generated />
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Application.Persitance;
namespace Application.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
partial class ApplicationDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.1.2-rtm-30932")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy",
SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("Application.Models.Make", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy",
SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(255);
b.HasKey("Id");
b.ToTable("Makes");
});
modelBuilder.Entity("Application.Models.Model", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy",
SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<int>("MakeId");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(255);
b.HasKey("Id");
b.HasIndex("MakeId");
b.ToTable("Models");
});
modelBuilder.Entity("Application.Models.Model", b =>
{
b.HasOne("Application.Models.Make", "Make")
.WithMany("Models")
.HasForeignKey("MakeId")
.OnDelete(DeleteBehavior.Cascade);
});
#pragma warning restore 612, 618
}
}
}
__EFMigrationsHistory DB Image:
Usually this happens when you include context.Database.EnsureCreated(); in your seed data file. This method doesn't allow to create a migrations table and cannot be used with migrations. You need to remove migrations with Remove-Migration command or delete the Migration folder and the database in your server and create new migration. Check Microsoft docs for better understanding.
I was having a similar issue. The Up method was empty despite cleaning the migrations folder and running dotnet ef migrations add Initial multiple times.
The solution in my case was to change the DbSet properties and add virtual to each of them.
Instead of
public DbSet<Make> Makes { get; set; }
try
public virtual DbSet<Make> Makes { get; set; }

Use UIOMaticField or backoffice controls in Ui-O-Matic Umbraco

I am new to Umbraco CMS. I am using Ui-O-Matic plugin in my project.
Ui-O-Matic allows easy CRUD operation for database. But I want to use backoffice controls like file, textarea, etc.
So I am using UIOMaticFielld like this in database.cs file.
[Column("newsDetail")]
[UIOMaticField("News Detail","Add Details",View ="textarea")]
public string newsDetail { get; set; }
[Column("newsImage")]
[UIOMaticField("Image","Upload Image",View ="file")]
public string newsImage { get; set; }
Problem is when I make any change in database, I have to refresh database.tt file to get database changes. But it recreates database.cs file and my previous changes:
[UIOMaticField("News Detail","Add Details",View ="textarea")]
removes from database.cs file. And every time I have to do the same changes.
Please guide me what should I do to keep my custom changes as it is even I refresh database.tt file?
Other better way to do CRUD operation is also preferable.
After googling a lot, I found that as database.cs file is auto generated, I must not do custom changes in it.
I found another way to use backoffice controls. Let me explain here, may it will help to other.
Instead of writing UIOMatoicField in databse.cs file, create model to do the same.
Make below changes in "Models/Generated/database.tt" file
// Settings
ConnectionStringName = "umbracoDbDSN"; // Uses last connection string in config if not specified
Namespace = "Generator";
RepoName = "";
GeneratePocos = true;
ClassPrefix = "";
ClassSuffix = "";
// Read schema
var tables = LoadTables();
tables["Course"].Ignore = true; // Prevents table to include in databse.cs file
tables["News"].Ignore = true;
if (tables.Count>0)
{
#>
<## include file="UIOMatic.Generator.ttinclude" #>
<# } #>
Then create new Model as below. For ex. "Models\NewsModel.cs"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using UIOMatic.Attributes;
using UIOMatic.Enums;
using UIOMatic.Interfaces;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.DatabaseAnnotations;
namespace EdumentUIOMatic.Models
{
[Umbraco.Core.Persistence.TableName("News")]
[PrimaryKey("newsId")]
[UIOMatic("News", "icon-box-open", "icon-box-open", RenderType = UIOMaticRenderType.List, ConnectionStringName = "umbracoDbDSN")]
public class NewsModel: IUIOMaticModel
{
[UIOMaticIgnoreField]
[Column("newsId")]
public int newsId { get; set; }
[Column("newsTitle")]
[UIOMaticField("News Title", "Add Title")]
public string newsTitle { get; set; }
[Column("newsDetail")]
[UIOMaticField("News Detail", "Add Details", View = "textarea")]
public string newsDetail { get; set; }
[Column("newsImage")]
[UIOMaticField("Image", "Upload Image", View = "file")]
public string newsImage { get; set; }
[Column("isDeleted")]
[UIOMaticField("Hide News", "Check if you want to hide this news")]
public bool isDeleted { get; set; }
[System.Web.Http.AcceptVerbs("GET", "POST")]
public IEnumerable<Exception> Validate()
{
return new List<Exception>();
}
}
}
Now if you will reload database.tt file to get updated database, your code will not be removed.

What is a good way to insert an entity with dependencies using TableController?

I am struggling to insert a new entity which references other existing entities using table controller in azure mobile services.
This is my set up:
Entities:
public class EntityB : EntityData
{
public EntityA Parent { get; set; }
//some data
}
public class EntityA : EntityData
{
//some data
}
Dtos:
public class DtoEntityB : EntityData
{
public DtoEntityA Parent { get; set; }
//some data
}
public class DtoEntityA : EntityData
{
//some data
}
Controller:
public class Controller : TableController<DtoEntityB>
{
public virtual async Task<DtoEntityB> Post(DtoEntityB entity)
{
return await InsertAsync(entity);
}
}
Mapper:
AutoMapper.Mapper.Initialize(cfg =>
{
// use other mapper
cfg.CreateMap<DtoEntityB, EntityB>();
cfg.CreateMap<EntityB, DtoEntityB>();
cfg.CreateMap<DtoEntityA, EntityA>();
cfg.CreateMap<EntityA, DtoEntityA>();
}
EntityA exists already, so I make a client call which results in JSON sent to the Post method. Then everything works fine until EF tells me that there is already an EntityA with id = 317238621736.
{
"EntityA" : {
"Id" : "317238621736"}
}
I am looking for a generic solution for this problem (right now I do direct operations on the context (attach) for every existing reference, combing this with Mapper makes this approach unsustainable.

Entity Framework 6 Code First Fail

I'm new in Entity Framework and I'm testing a simple application but it doesn't work.
Let me explain step by setp what I'm doing:
1- Create a Console App using VS 2013 Express
2- Include a reference to EF6 by Nuget
3- Create the Student Class:
namespace CSharp_CodeFirst
{
public class Student
{
public int Id { get; set; }
public string name { get; set; }
public string email { get; set; }
}
}
4- Create the context class
using System.Data.Entity;
namespace CSharp_CodeFirst
{
public class StudentDataContext : DbContext
{
public StudentDataContext() : base()
{
}
public DbSet<Student> Students;
}
}
5- Create the code in Program.cs
namespace CSharp_CodeFirst
{
class Program
{
static void Main(string[] args)
{
using (var ctx = new StudentDataContext())
{
Student stud = new Student() { name = "New Student", email="test#test.com" , Id=1 };
ctx.Students.Add(stud);
ctx.SaveChanges();
}
}
}
}
6- Build without errors
7- When I execute the project I get the error :
An unhandled exception of type 'System.NullReferenceException' occurred in CSharp_CodeFirst.exe
Object reference not set to an instance of an object.
The error occur in this line of code : ctx.Students.Add(stud);
I'm using the sample in this site : http://www.entityframeworktutorial.net/code-first/simple-code-first-example.aspx
I Feel Like I'm Forgetting Something, but What ???
Thanks

How to use a custom class in Odata v4 instead of class from designer.cs

C# Web.Api Odata APplication
I’m implementing Odata V4 for the first time and would like to use my own custom class instead of the data class from the designer.
Here is what I did:
I created a Data project in Visual Studios and added my SQL Linq data table “Video”
I created the data context as follows:
public class VideoDataContext : DbContext
{
public VideoDataContext(): base("name=VideoData")
{
DbSet<VideoEf> Videos { get; set; }
}
And my custom class as follows:
[Serializable]
[DataContract]
public class VideoEf : Repository
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Isrc { get; set; }
}
And model builder:
public Microsoft.OData.Edm.IEdmModel GetEdmModel()
{
ODataModelBuilder builder = new ODataConventionModelBuilder();
EntityTypeConfiguration<VideoEf> titleType = builder.EntityType<VideoEf>();
builder.EntitySet<VideoEf>("Video");
return builder.GetEdmModel();
}
And in my video controller:
public class VideoController : ODataController
{
VideoDataContext db = new VideoDataContext ();
[EnableQuery(PageSize = 20, MaxExpansionDepth = 5)]
public IHttpActionResult Get()
{
return Ok(db.Videos.AsQueryable());
}
When I make the call to get the video entities I keep getting a ” 406 Not Acceptable” error message
How can I ensure that the data returned from the database is mapped to my custom model ?
Is my model builder correct?
what could be causing the above error?
You don't need to return IQueryable because you have EnableQuery attribute, just return DbSet.
You also don't need any wcf attribute and EntityTypeConfiguration<VideoEf> titleType = builder.EntityType<VideoEf>();
Then it should just work.
Hope it helps.
Edit
My mistake for IQueryable, I also use it.

Resources