我正试图用MySQL数据库中的Entity Framework Core向ASP.Net中提取大量注入(22位以上)的问题。
EF Core不支持BigInteger
以及我收到的建议,而不是decimal
。但是,在我的实体上使用decimal
类型时,在尝试从数据库中进行选择时,我总是会收到以下异常:
System.InvalidCastException:无法转换类型的对象 ' System.Int32'输入' System.Decimal'
在数据库中,列为INT(25)
,在我的模型中,类型为decimal
,这是一个示例模型:
[Table("alliance_reputation_rankings")]
public class AllianceReputationRank
{
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
[Column("date")]
public DateTime Date { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
[Column("world")]
public int World { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
[Column("alliance")]
public string Alliance { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
[Column("rank")]
public int Rank { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
[Column("reputation")]
public decimal Reputation { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
[Key]
[Column("entry_id")]
public int EntryId { get; set; }
}
我无法使用EF Core选择Reputation
属性。即使我尝试在属性之前使用(decimal)
来投射它:
选择的粗略示例:
_context.AllianceReputationRankings
.Where(p => p.Date == rank.Date && p.Alliance== rank.Alliance && p.World == rank.World)
.Select(pl => new AllianceReputationRank
{
Date = pl.Date,
World = pl.World,
Alliance = pl.Alliance,
Reputation = (decimal)pl.Reputation
}
).FirstOrDefault();
如何在模型中使用小数来从数据库中引入大量内容?如果我不能使用小数,我如何在EF Core中使用大数字?
答案 0 :(得分:1)
我所做的似乎奏效的是乘以1m
:
context.AllianceReputationRankings
.Where(p => p.Date == rank.Date && p.Alliance== rank.Alliance && p.World == rank.World)
.Select(pl => new AllianceReputationRank
{
Date = pl.Date,
World = pl.World,
Alliance = pl.Alliance,
Reputation = pl.Reputation * 1m
}
).FirstOrDefault();
这似乎允许十进制运算,而不会降低性能。
答案 1 :(得分:0)
实体框架期望数据库和模型之间存在非常紧密类型约束,它实际上不希望看到具有decimal
属性的数字列。我在这里列出了几个选项,每个选项都有自己的优点和缺点。随意使用最适合您的一个。
由于您使用的是MySQL,我推荐的第一个选项是您可以将列类型从 如果你做不到,那么,遗憾的是,你处在一个非常紧张的角落里。实体框架核心只是不是这项工作的正确工具,它还不够成熟。在评论中,您澄清了您在数据库中使用此数字列进行数学运算,这意味着 此解决方案依赖于此整个模型是只读的假设。如果是(并且不需要从Entity Framework Core更新数据库),那么您可以在MySQL中构建一个 问题在于你无法通过 最后,最后一个选项是使用存储过程/方法进行读写。然后,您可以向其传递 然后构建第二个存储过程/方法来进行更新。您可以调用 类似的东西: 建立相反的方法恰恰相反。 老实说, 我希望我们有更好的消息,但是没有能力构建我们自己的可映射类型(即构建我们自己的实体框架核心支持的INT(25)
更改为DECIMAL(25, 0)
。然后,您应该能够在实体框架中使用decimal
,以便尽可能多地使用。
string
和VARCHAR(25)
不在游戏手册中,除非您可以使用该数学 out 的数据库。VIEW
,将INT(25)
列转换为a VARCHAR(25)
,并执行以下操作:[NotMapped]
public BigInteger ReputationValue { get; set; }
public string Reputation
{
get
{
return ReputationValue.ToString();
}
set
{
ReputationValue = BigInteger.Parse(value);
}
}
VIEW
真正更新数据库,所以如果你想更新这些记录(基本上与整个模型有关),你需要编写手册SQL,或构建存储过程。这只是实体框架核心的一个限制,无法轻易获得。WHERE
子句(如果您想接受构建C#样式转换的挑战,请执行此操作,否则只需添加传递给方法的WHERE sqlConditionCode ...
字符串即可过滤东西。dbContext.Update(model)
将所有内容传递给存储过程进行更新,dbContext.Get("WHERE EntryId = @EntryId", new List<SqlParamter> { new SqlParamter("@EntryId", ...) })
我确定您已明白这一点。public IEnumerable<AllianceReputationRank> GetAllianceReputationRanks(string whereClause, IEnumerable<MySqlParameter> parameters)
{
// Get a connection string from somewhere
var connectionString = string.Empty;
using (var connection = new MySqlConnection(connectionString))
using (var command = new MySqlCommand("SELECT * FROM alliance_reputation_rankings " + (whereClause ?? string.Empty), connection))
{
connection.Open();
foreach (var parameter in parameters)
{
command.Parameters.Add(parameter);
}
using (var reader = command.ExecuteReader())
{
if (reader.HasRows)
{
// Build a list or use `yield return`, if building a list instance here
var result = new List<AllianceReputationRank>();
while (reader.Read())
{
// Build a model of `AllianceReputationRank` here
var model = new AllianceReputationRank();
// Use reflection or just add each property manually
model.Date = reader.GetDate("date");
// ...
// Make sure you read `reputation` as a string, then `BigInteger.Parse` it to your model
model.Reputation = BigInteger.Parse(reader.GetString("reputation"));
// Either add the model to the list or `yield return model`
result.Add(model);
}
// If you built a list then `return` it
return result;
}
}
}
}
?? string.Empty
可能是多余的,我不会在我面前设置一个IDE,以检查string + null
是否会引发异常,但如果您不喜欢它,则可以删除它。 (在我看来,这比对不起更安全。)我真的希望我的所有类型和用法都是正确的,如果没有,我为除了添加连接字符串和其他属性之外的任何修改道歉。DECIMAL(25, 0)
选项应该对你有用,如果那不存在那么存储过程/方法选项应该。两者都应该将数学保留在数据库中,并希望在破坏实体框架核心问题的同时不破坏任何其他内容。是不理想?当然,我希望它不是必要的。但是,不幸的是,实体框架核心非常新,并且仍然需要大量更新才能添加Entity Framework not-Core所具有的简单功能。 (例如Like the lack of a .Find
method in Entity Framework Core。)BigInteger
)只有 isn&#t; t < / em>要解决这个问题还有很多工作要做,我们会坚持使用恶劣的解决办法让它做我们需要的工作。