Entity Framework and Default Date - entity-framework

I have a table in SQL, within that table I have DateTime column with a default value of GetDate()
In entity framework I would like it to use the SQL date time instead of using the local date time of the computer the console app is running on (the SQL server is 1 hour behind).
The column does not allow nulls either, currently it passes in a date value of 1/1/0001 and I get an error:
The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value.\r\nThe statement has been terminated.
Thank you!

Open edmx designer
Select your DateTime column
Go to properties and change StoreGeneratedPattern from None to Computed
That will tell EF not to insert value for that column, thus column will get default value generated by database. Keep in mind that you will not be able to pass some value.

If you're using Fluent API, just add this to your DbContext class:
modelBuilder.Entity<EntityName>()
.Property(p => p.PropertyName)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);

Set columnType for that entity in OnModelCreating Method:
modelBuilder.Entity().Property(s => s.ColumnName).HasColumnType("datetime2");

Related

Entity Framework writing NULL to the DB

I am using EF v 6.2.0. My issue is similar to the SOF question - Entity Framework not claiming datetime.now is null. However, the proposed solution does not work for me.
buildDetail.BuildTime = epoch.AddMilliseconds(Double.Parse(buildTime)).ToLocalTime();
:
:
: // Other properties.
ps.dbEntities.BuildDetails.Add(buildDetailT);
ps.dbEntities.SaveChanges();
On the SaveChanges() line, I get an exception
Inner Exception 2:
SqlException: Cannot insert the value NULL into column 'BuildTime', table 'BuildDetailsDB.dbo.BuildDetails'; column does not allow nulls. INSERT fails.
The statement has been terminated.
The buildDetail.BuildTime property, when I hover over in debug, shows the value as {3/29/2018 9:17:22 AM} i.e. current date time. The datatype in Sql Server is datetime and the model I have generated from the database shows that this field has a return value of System.DateTime. So, I am frustrated as to why EF is trying to insert a null. In fact, if I allow nulls for this columns in the DB, that is exactly what it writes in that column - NULL.
The field in question is neither marked as Identity (both in model and db) nor Calculated. I have also updated the model from the Database and they are in sync.
Note: I have tried the DateTime.ParseExact and even an DateTime object converted from a string in the exact same format as expected in SQL Server i.e. "yyyy-MM-DD HH:MM:SS.FFF" with no luck and the same exception. eg.
buildDetailT.BuildTime = DateTime.Parse("2018-11-25 08:25:26.0000");

EF Table per Hierarchy (TPH) not saving because can't insert value null in Discriminator column

I have a table used for multiply type of category and it contains a Discriminator column named 'ClassName' to specify the type of object to load. The ClassName column is non nullable with a default value of 'Category'
My problem is when saving a new item , I get the error :
'Cannot insert the value null into column ClassName' table Category.
I tought that ef would set the ClassName value base on the new object class.
How can I save my object with the right 'ClassName' value ?
I changed my db Structure to accept null. EF will set null if the object name match the table name and will set the discreminator name for the derived classes.
It's old question but I just met it today. In .net 4.0 code first I don't meet "disclaimer column" but when downgrade to net 3.5, it make me tired for a day.
This is my solution
Change the column in the database to ALLOW NULL (using alter table)
and update the edmx file to make it update the change(allow null)

Problem with ConcurrencyCheck attribute approach in EF

I've found two ways of concurrency checking for my entities in EF 4.1:
TimeStamp attribute for byte array
ConcurrencyCheck attribute for another types
The first one is very simple. You just mark byte array property as TimeStamp, create additional column in database and voila...
I've got a problem with the second method. Enity Framework has started generate sql script for concurrency check, when I marked the LastUpdateDate property.
Property:
[ConcurrencyCheck]
public DateTime LastUpdateDate { get; set; }
Sql:
select
...
where (([Id] = #3) and ([LastUpdateDate] = #4))
...
#4='value'
But EF does not generate sql script for updating the value of LastUpdateDate?
Is it possible to say EF to update the LastUpdateDate after concurrency checking without triggers or something like this?
And the second question:
What is the best practice of using concurrency checking in EF when you have something like LastUpdateDate property(property will be displayed in UI)? Is it better to check concurency using LastUpdateDate and avoid creating of addtional column for TimeStamp in your tables or
create additional TimeStamp property and renounce of the using DateTime property for concurrency checking?
Have you tried to use a rowversion (timestamp) instead of the DateTime datatype to check for concurency?
I would use the timestamp, because you are sure that the system will update it for you. Further more the value will be very precice.
The following blog posts will give you more information about how to map a timestamp.
The first one shows how to use the timestamp as a concurrency check.
Code First Optimistic Concurrency with Fluent Assertions
Round tripping a timestamp field with EF4.1 Code First and MVC 3

How to manage GetDate() with Entity Framework

I have a column like this in 1 of my database tables
DateCreated, datetime, default(GetDate()), not null
I am trying to use the Entity Framework to do an insert on this table like this...
PlaygroundEntities context = new PlaygroundEntities();
Person p = new Person
{
Status = PersonStatus.Alive,
BirthDate = new DateTime(1982,3,18),
Name = "Joe Smith"
};
context.AddToPeople(p);
context.SaveChanges();
When i run this code i get the following error
The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value.\r\nThe statement has been terminated.
So i tried setting the StoreGeneratedPattern to computed... same thing, then identity... same thing. Any ideas?
You have to manually edit the edmx xml and set your SSDL StoreGeneratedPattern attributes to identity or computed. But whenever you update your edmx via the designer your changes will get overwritten.
This is a known issue. Please see the following links for more details:
Microsoft Connect Ticket
Using a GUID as an EntityKey in Entity Framework 4
I had the same problem! For me it works like this:
Database MS SQL Server express:
[RowTime] [datetime2](7) NOT NULL
ALTER TABLE [dbo].[Table_1] ADD CONSTRAINT [DF_Table_1_RowTime] DEFAULT (getdate()) FOR [RowTime]
GO
Then I import the table from database to my Entities model.
Entities will not realise the default value!
So, you have to set the StoreGeneratedPattern of the column to Computed.
Then Entities will not put there any default value any more.
Combination of:
datetime2,
NOT NULL,
StoreGeneratedPattern=Computed
Works for me!
Changing type of DateCreated to datetime2 might solve the problem.
datetime 2007-05-08 12:35:29.123
datetime2 2007-05-08 12:35:29. 12345
Ref: http://technet.microsoft.com/en-us/library/bb677335.aspx67
Here is a working workaround:
1) Change the column to datetime2 as mentioned elsewhere. This fixes the conversion error.
2) Add a trigger that sets DateCreated to getdate();
CREATE TRIGGER [TR_AS_ChangeTime] ON [AS_ApplicationSession]
AFTER INSERT,UPDATE AS
BEGIN
SET NOCOUNT ON;
UPDATE AS_ApplicationSession
SET AS_ChangeTime = getdate()
WHERE AS_Id IN(SELECT AS_ID FROM INSERTED)
END
3) If neccessary, set
p.DateCreated = DateTime.MinValue;
just to initialize it.
4) If you need the DateCreated from the database, add
context.Refresh(System.Data.Objects.RefreshMode.StoreWins, p);
just after
context.SaveChanges();
Focusing on the fact that I do not want change the database, since it is an application problem and I expect them to solve this problem one day, my solution (that is totally possible in my case) is to create a partial class of the model to correct the problem on constructor:
public partial class Log
{
public Log()
{
this.Date = DateTime.Now;
}
}
This works for me because:
I create the model on the moment I send it to database.
I use CLOUD for these services, the datetime must be the same in both Application and Database servers!
Don't forget that the namespace needs to match the Model namespace or partial should not list properties (and should no be partial as well ;])!

How do I get the entity framework to stop setting the rowversion field?

Im using the Entity Framework and I have a rowversion (timestamp) field on a table to use for concurrency. However, when updating the entity object, it keeps trying to set the rowversion column to null, and I get an error:
The 'VerCol' property on 'LmpDemoRequest' could not be set to a 'null' value. You must set this property to a non-null value of type 'Byte[]'.
I have the VerCol column within the entity definition, but I am unable to remove the "Setter" function.
How do I get the entity framework to stop attempting to set this column?
You can pass any arbitrary, valid values for the RowVersion fields (DateTime.Now for example). They will be overwritten with the server-generated values.
For future releases of EF, there should be support for "shadow properties", which exist in the model but not in your classes. That feature would be useful in situations such as this.
I had a case where a view included a RowVersion column from a table that was left joined in the view... so that column could be null sometimes.
But EF4 'knows' that a RowVersion column cannot be null, so even in a simple LINQ query, it was throwing an InvalidOperationException:
The 'PersonRowVersion' property on 'vVoteInfo' could not be set to a 'DBNull' value. You must set this property to a non-null value of type 'Byte[]'
I finally had to change the view to use this for the RowVersion column, so that EF would be happy:
coalesce(p._RowVersion, cast(0 as binary(6))) [PersonRowVersion]