问题:我应该在数据库和类中使用什么类型的列才能正确运行应用程序?
项目:https://github.com/jhon65496/TypeDataCnsl01
由 SQLite
使用IndexValue
、Discount
列有问题。目标是从数据库获取数据并执行计算。
如果:
IndexValue
、Discount
的类型为 DECIMAL(10, 5),
;Index
类中,字段 IndexValue
、Discount
的类型为 string
。然后就没有问题了,我得到了数据。
如果
IndexValue
、Discount
的类型为 DECIMAL(10, 5)
;IndexValue
、Discount
的类型为 decimal
。我在调试时遇到错误。
错误:
呼叫接收者已创建例外
线路发生错误
var items = indexesRepository.Items.toArray();
在 `IndexesViewModel' 类中的
Load Data()
方法中。
public class IndexesViewModel
{
// ...
// Code
// ...
public void LoadData()
{
var items = indexesRepository.Items.ToArray();
Indexes = new ObservableCollection<Index>(items);
}
}
使用:
代码
Index
班级:
[Table("Indexes")]
public class Index
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
// decimal
// float
public decimal IndexValue { get; set; }
public decimal Discount { get; set; }
}
DbContextIndexes
:
public class DbContextIndexes : DbContext
{
static SQLiteConnection sqliteConnection;
public DbContextIndexes() : base("DefaultConnection")
{
}
public DbSet<Index> Indexes { get; set; }
}
IndexesRepository
:
class IndexesRepository
{
private readonly DbSet<Index> _Set;
DbContextIndexes _db;
public IndexesRepository(DbContextIndexes db)
{
_db = db;
_Set = _db.Set<Index>();
}
private IQueryable<Index> items;
public virtual IQueryable<Index> Items
{
get
{
items = _Set;
return items;
}
set
{
items = value;
}
}
}
IndexesViewModel
:
public class IndexesViewModel
{
IndexesRepository indexesRepository;
DbContextIndexes DataContextApp;
public IndexesViewModel()
{
this.DataContextApp = new DbContextIndexes();
indexesRepository = new IndexesRepository(this.DataContextApp);
LoadData();
}
private ObservableCollection<Index> indexes;
public ObservableCollection<Index> Indexes
{
get { return indexes; }
set
{
indexes = value;
}
}
public void LoadData()
{
var items = indexesRepository.Items.ToArray(); // <== Тут ошибка !!!
Indexes = new ObservableCollection<Index>(items);
}
}
SQL 索引:
CREATE TABLE "Indexes"
(
"Id" INTEGER UNIQUE,
"Name" VARCHAR NOT NULL,
"IndexValue" DECIMAL(10, 5),
"Discount" DECIMAL(10, 5),
"Description" TEXT,
PRIMARY KEY("Id" AUTOINCREMENT)
);
packages.config
:
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="EntityFramework" version="6.4.4" targetFramework="net48" />
<package id="Stub.System.Data.SQLite.Core.NetFramework" version="1.0.118.0" targetFramework="net48" />
<package id="System.Data.SQLite" version="1.0.118.0" targetFramework="net48" />
<package id="System.Data.SQLite.Core" version="1.0.118.0" targetFramework="net48" />
<package id="System.Data.SQLite.EF6" version="1.0.118.0" targetFramework="net48" />
<package id="System.Data.SQLite.Linq" version="1.0.118.0" targetFramework="net48" />
</packages>
App.config
:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=dbAppIndexes.db" providerName="System.Data.SQLite" />
</connectionStrings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
<entityFramework>
<providers>
<provider invariantName="System.Data.SQLite" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
<!--<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />-->
<provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
</providers>
</entityFramework>
<system.data>
<DbProviderFactories>
<remove invariant="System.Data.SQLite.EF6" />
<add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6" />
<remove invariant="System.Data.SQLite" /><add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" /></DbProviderFactories>
</system.data>
</configuration>
屏幕截图#1:
屏幕截图#2:
正在工作。
将逗号
,
替换为句点 .
。
重点是什么?
我可以仅用分号将数据存储在数据库中吗?
我可以不将数据存储在数据库中吗?
我应该选择哪种类型来存储 IndexValue 和 Discount 字段。
问题可能是数据库服务器与执行 .Net 代码的服务器或客户端之间的区域设置存在差异。默认情况下,.Net 将使用系统区域设置,其中包括数字格式的设置,特别是“数字分组符号”和“小数点符号”,以及较小程度的“列表分隔符”。
国家之间,有些使用“.”。表示小数点分隔符,“,”表示分组分隔符,而其他国家/地区使用“,”表示小数点,使用“.”。用于分组,当为一个服务器设置的服务器收到为另一个服务器设置格式的数字时,事情会变得非常混乱。在内部,小数就是小数,符号设置影响它们如何显示为字符串或从字符串解析。由于 EF 正在有效地构建 SQL 以针对数据库运行,因此这成为一个问题,因为最终它会将您的十进制值转换为字符串,除非使用相同的数字格式,否则数据库将无法理解该字符串。
解决问题的第一个选项是确保两台服务器(假设是 ASP.Net 应用程序)Web 服务器和数据库服务器使用相同的区域文化设置,因此期望相同的数字格式。
如果该选项不实用,那么您可以在初始化时以编程方式更新 Web 服务器的区域性设置:
var cultureInfo = new CultureInfo("en-US");
CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;
如果 Web 服务器设置/托管在俄罗斯或东欧,则数据库安装默认为美国英语数字格式。
对于 Web 应用程序本身,客户端可能使用具有不同 UI 文化设置的系统,您需要了解每个客户端在登录时使用的 UI 文化,或者基于浏览器的请求标头,并使用它来解析和格式化任何内容。进出客户端浏览器的十进制值。