如果将DateTime属性注释为Date类型,我的Entity Framework(V 6.1.0)存在问题:
列(TypeName =“Date”)
public class MyTable
{
[DatabaseGenerated]
public Guid Id { get; set; }
[Key, Column(TypeName = "Date"), DataType(DataType.Date)]
public DateTime DateKey { get; set; }
[Required]
public string SomeProperty { get; set; }
}
SQL中我的表的列是作为DATE列正确创建的。
现在,如果我尝试插入新行并设置我的日期属性,例如使用DateTime.Now()我收到以下错误:
存储更新,插入或删除语句会影响意外 行数(0)。自那以后,实体可能已被修改或删除 实体已加载。刷新ObjectStateManager条目。
问题在于EF生成的SQL代码:
exec sp_executesql N'
INSERT [dbo].[MyTable]([DateKey], [SomeProperty]) VALUES (@0, @1)
SELECT [Id] FROM [dbo].[MyTable]
WHERE @@ROWCOUNT > 0 AND [DateKey] = @0',
N'@0 datetime2(7), @1varchar(max)',
@0='2014-03-26 08:58:07',
@1='abcdef'
DateKey的参数声明为DATETIME2。我想,这应该是DATE。 如果有任何时间部分,则此select语句不能返回任何行。如果我将参数@ 0更改为DATE(因为它在我的模型中注释,即使时间部分仍然包含在内,我也没有错误。
这是EF中的错误吗?
此致 丹尼尔
编辑: 我不知道这是否与我的问题相关。我默认在OnModel中将所有日期列配置为DATETIME2:
modelBuilder.Properties()。Configure(p => p.HasColumnType(“datetime2”));
2014-03-27编辑 提供完整的复制品:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EFDateColumnAsKey
{
class Program
{
static void Main(string[] args)
{
MyContext ctx = new MyContext();
ctx.CalendarItems.Add(new CalendarItem() { StartDate = DateTime.Now.Date }); // This works
ctx.SaveChanges();
ctx.CalendarItems.Add(new CalendarItem() { StartDate = DateTime.Now }); // This not !!
ctx.SaveChanges();
ctx.Dispose();
}
public class MyContext : DbContext
{
public DbSet<CalendarItem> CalendarItems { get;set; }
}
public class CalendarItem
{
[DatabaseGenerated( System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Key, Column(Order = 1), DataType(DataType.Date)]
public DateTime StartDate { get; set; }
}
}
}
答案 0 :(得分:0)
我在bug #2185中添加了一些细节。总之,当我们为INSERT操作创建一个SqlCommand时,我们为System.DateTime类型的任何属性定义类型为DATETIME2的参数,但出于兼容性原因,我们默认创建数据库模式时,我们将创建一个DATETIME类型的列。
我们为插件生成的SQL如下所示:
INSERT [dbo].[CalendarItems]([StartDate]) VALUES (@0);
SELECT [Id] FROM [dbo].[CalendarItems] WHERE @@ROWCOUNT > 0 AND [StartDate] = @0;
当您将任意System.DataTime实例作为DATETIME2参数传递时,将保留最低有效数字,但只要DATETIME2参数的值存储在DATETIME列中,该值就会被截断。
由于存储在StartDate中的值不再与参数@0的值匹配,因此第二个语句(即我们用于检测受影响的行的SELECT查询)将返回零行并且命令将失败,事务将被回滚等等。
正如您已经发现的那样,可能的解决方法是:
希望这有帮助, 迭