我正在开发的项目使用Entity Framework 6.0 Code-First。
由于他缺乏EF经验,我的一位同事手动将数据库中字段的字段类型更改为decimal(28,10)
,而不是在{{1}中正确地执行此操作} OnModelCreating
的方法。实体框架允许他这样做,从未在任何未来的迁移中抛出错误。
上周,另一位同事遇到了一个问题,该进程克隆了该表中的记录,其中新记录中的十进制值被截断为2位小数(没有发生舍入)。
该克隆的代码类似于以下内容(使用EF顶部的Repository模式):
DbContext
当我指出,作为一个侧点,public void CloneAccounts(List<Account> accounts, int newQuarterID)
{
var newAccounts = new List<Account>();
accounts.ForEach(account =>
{
var clonedAccount = new Account
{
QuarterID = newQuarterID
AccountName = account.AccountName,
AccountNumber = account.AccountNumber,
Amount = account.Amount
};
newAccounts.Add(clonedAccount);
});
AccountRepository.AddMany(newAccounts);
AccountRepository.Save();
}
字段Amount
的声明真的应该在decimal(28,10)
时,他继续这样做,并添加了迁移。有趣的是,这样做最终解决了上述代码的问题。
我的问题是双重的:
OnModelCreating
中添加该行修复它?谢谢!
答案 0 :(得分:0)
如果您最初没有任何精度集,则代码优先的默认约定是使用precision of 18 and scale of 2创建十进制列(因此只有两位小数)。我认为这些记录最初可能被截断了。
此外,默认情况下,SQL Server提供程序的SQL生成器将SqlParameter.Scale
属性设置为模型中定义的比例,除非您将TruncateDecimalsToScale设置为false,这将影响数据库更新和插入。我不确定那些带有额外小数位的记录是如何在数据库中结束的。
答案 1 :(得分:-1)
将codeFirst与EF一起使用时,它会在代码(C#或VB)中创建模型,然后将模型复制到数据库中。
要回答你的问题我可以说:
请记住,Entity Framework是一个ORM(对象关系映射器),它为您创建一个基于域模型的一组实体(类) - 这个域模型可以存在三种不同的风格:代码 - 首先,模型优先,数据库优先。
代码优先意味着您可以通过创建一组类(aKa实体)来启动项目,这些类将代表数据库中的关系模型。 (您的来源将是您的类,目标是您的数据库)。
模型优先意味着您可以使用可视化工具启动项目,基本上是拖放,连接点等,这样您就可以创建一个模型来表示数据库中的关系模型。 (您的来源将是您的模型,目标是您的数据库)。
数据库优先意味着您通过从数据源(通常是数据库)中选择模型来启动项目,此方法将为您在visual studio项目中创建一组类(实体)。 (您的来源将是您的数据库,目标是您的代码)。
因此,无论您在上述任何场景中所做的任何更改都必须通过Entity Framework从源代码复制到目标。
这里发生的是你的同事的错误,他直接在你的数据库中进行了更改,但它必须是从你的EF项目(代码优先)完成的。
当您调用ClonneAccounts时,EF制作了所有魔法(连接到数据库,执行查询,获取数据,将其强制转换为实体类,然后检索它们或内容) - &gt;这是因为InvalidCastException导致您的应用程序崩溃。
希望有所帮助