MVC4 Code First Database type "Date" - asp.net-mvc-4

I need a database column to be a date data type in a MS SQL Server. It's a requirement for the project, it cannot be datetime.
In my model I have:
[DataType(DataType.Date)]
public DateTime? RequestedCompletionDate { get; set; }
This still creates the column as a nullable datetime. Is there any way to make it date code first?

After a lot of research I finally figured out how to do it.
In my model rather than using the DataType attribute I used the column attribute. My model now looks like this:
[Column(TypeName="date")]
public DateTime? RequestedCompletionDate { get; set; }
If anyone is trying to do something similar, although I used TypeName="date", you should be able to set TypeName to anything you want as long as it is a valid SQL Server Data Type.

Related

ASP.NET MVC Core date only format is not working using DataAnnotation

Following viewmodel used in a view is supposed to display a StartDate as, say 9/30/2015. But it is displaying as 9/30/2015 12:00:00 AM. How can I make it display without time while using DataAnnotaion? I know I can use #Model.StartDate.ToString("MM/dd/yyy") inside view to display date only. But that would mean you have to do it in every view that is using the following ViewModel:
ViewModel:
...
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime StartDate { get; set; }
...
UPDATE
The corresponding model class of the above ViewModel already has the following DataAnnotation that correctly creates the data type in SQL Server table as Date; and when you run a query on the corresponding table in SSMS it correctly displays the StartDate column's data with dates only, say, 9/30/2015 etc.)
Model
...
[DataType(DataType.Date)]
public DateTime StartDate { get; set; }
...
StartDate in the sql db is in fact Date only. Moreover, if I run a query on SSMS it correctly returns date only.
There are two solutions to your problem. As per your comments, you are currently using #Model.StartDate to display a date.
You can either do this:
#Model.StartDate.ToString("d")
Or, you can use a model based approach in your ViewModel and do this:
[DataType(DataType.Date)]
public DateTime StartDate {get;set;}
Then, in your view use:
#Html.DisplayFor(m => m.StartDate)

Changing data type of a model property without affecting data

We are using Code First approach in one of our ASP.NET MVC Core app. We have a table with lots of data in it and we want to change the data type of one of its column from string to int.
The column is storing only two integers, being "1" and "2". How will we do it using Package Manager console command (or something like that) without affecting the data.
So, in the following model we need to change OrderType from string to int without affecting existing data in the SQL Server database:
public class Order
{
public int OrderId { set; get; }
public string OrderType { set; get; }
public int OrderYear { set; get; }
public string OrderLoc { set; get; }
...
...
}
UPDATE
We're using VS2015 with latest updates. Following may be a better explanation of our question:
In ASP.NET Core - Code First model sometimes you can make certain changes to a model and run a migration command to keep the changes in sync with the database that was originally created using Code First approach. I'm looking for such a migration command so if data type of a model property is changed to a compatible type the existing data in the corresponding column in the database table remains intact. Please note that in our case since column OrdererType is holding values 1 and 2 as string the existing data type string is compatible to data type int.
I resolved the issue as follows. Following are my observations:
It turned out that after making any changes to model - such as adding/deleting a property, changing a data type of a property or even deleting an existing entire model or adding a new model - if you run the following command in the Package Manager console of Visual Studio, a new migration file will be created - under Migrations folder in Visual Studio - reflecting those changes. And then when you run the second command shown below all your new changes will be reflected in the existing database (that was originally created using Code First approach). That's the changed data types in model will be changed accordingly in the corresponding SQL Db, deleted/added properties in the model will cause corresponding columns in the corresponding table in the corresponding SQL Db to be added/deleted accordingly, etc. etc. During all this process all your existing data will be intact if the corresponding new data types are compatible with the old data in the old data type etc.
How does it all happen: Whenever we run add-migration command Visual Studio creates a table called __EFMigrationsHistory in the database that keeps track of the changes created in the migration file.
Package Manage Console Commands:
First command:
PM> add-migration myNewMigration -context myWebProjContext
Note: When you run the above command, following message would warn you to review your changes in the newly created migration before you run the next command that would update the database reflecting all your changes:
An operation was scaffolded that may result in the loss of data. Please review the migration for accuracy.
To undo this action, use Remove-Migration.
Second command:
PM> update-database -context myWebProjContext
For example
After I made the following changes to the following model and ran the above commands, the Orders table in SQL Db had data type of OrderType as tinyint, and the columns OrderName and OrderDesc were dropped from the SQL db:
Old Model
public class Order
{
public int OrderId { set; get; }
public string OrderType { set; get; }
public int OrderYear { set; get; }
public string OrderLoc { set; get; }
public string OrderName { set; get; }
public string OrderDesc { set; get; }
}
Modification to the above Model: Here I changed the data type of OrderType from string to byte. And deleted the last two properties OrderName and OrderDesc
public class Order
{
public int OrderId { set; get; }
public byte OrderType { set; get; }
public int OrderYear { set; get; }
public string OrderLoc { set; get; }
}
Basically, all you have to do is:
PM: Add-Migration SomeNewName
(if 'SomeNewName' is already in your migration folder, delete it or give a new name.)
PM: Update-Database

why does a nullable datetime trying to validate the date, when it is empty?

I am building an MVC 4 application. I have the following property
[Display(Name = "ExpiryDateLabel", ResourceType = typeof(Resources.Manage.PrereqDetail))]
public DateTime? ExpiryDate { get; set; }
in my View when i post it back with an empty value it says
The field Expiry Date: must be a date
why is that happening?
Looks like you are doing localization on ExpiryDate property and if you are using jQuery validation, you might wanna check following post explaining the solution to same problem.
How to fix regional settings for jQuery datepicker so it works in Firefox and IE7?

How to write null to Guid? field in DB?

I have a guid? field in my POCO and when I create a new entry in my DB and look at it through SSMSE, I see NULL in that field. After choosing a manager for this new user entry, the guid? field is updated to hold the id of the new manager. However, if I want to change the user back to having no manager, how can I set the field back to NULL?
Should I be using Guid instead of Guid? and write Guid.Empty to the DB instead?
Should I be using Guid instead of Guid? and write Guid.Empty to the DB instead?
Not really. You could do that, but you wouldn't really gain much. Semantically, if there is "no" value for a field, NULL is the correct value. What you are talking about is using a magic value.
how can I set the field back to NULL?
Set the Guid? to null on your POCO. For example, if your POCO looks something like this:
public class Poco
{
public Guid? Manager { get; set; }
}
Set it to null like this:
somepocoinstance.Manager = null;
Then commit the changes.

Fluent-NHibernate and persisting DateTime automatically

I'm using S#arpArchitecture (ASP.NET MVC and Fluent NHibernate). I have an entity as follows:
public class User : Entity
{
public User(){}
public User(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public virtual DateTime? LastUpdate{ get; set; }
}
I will call the SaveOrUpdate method on my repository class that will persist this User object. It works. How would i persist the LastUpdate property automatically with the latest date and time? I could override the SaveOrUpdate method in my repository by always setting the LastUpdate property to the current date and time but that does not seem to be correct because if there's nothing changed in my entity, I don't think NHibernate will persist my object back to the DB and forcing the setting of this property will always make it persist back.
I only want this LastUpdate property set if something else has changed in my entity.
You should use an NHibernate Interceptor to accomplish this. Override OnFlushDirty in your interceptor implementation to set the LastUpdate property only when something has changed (i.e. your object is dirty).
Since you didn't specify your database type, I will take the liberty and add a solution for people using MySQL / MariaDB:
You can use the following in your fluent mapping class:
Map(y => y.LastUpdate).CustomSqlType("timestamp").Generated.Always();
This creates a MySQL TIMESTAMP column with a default value of CURRENT_TIMESTAMP. Thus, if Nhibernate chooses to flush your entity, MySQL will make sure that the column is properly updated.
I'm pretty sure this does not play well with MSSQL as TIMESTAMPS are different beasts in MSSQL (here and here)
I'm going to point to another StackOverflow question that I think answers my question.