问题
I have a table column defined like this:
ENTRY_STATUS NUMBER(2, 0)
And in my EntityFramework class the respective field is defined like this:
[Column("ENTRY_STATUS")]
public int Status { get; set; }
When checking the value to get an entry it works perfectly fine:
var order = testDbContext.Orders.FirstOrDefault(o => o.Status > 1);
But when I check the order entity after this statement it is always zero:
if (order != null)
{
if (order.Status == 3) //Always Zero!!!
{ //Do something...
}
}
What went wrong here with my definitions? How do I fix this?
回答1:
The Oracle Database Column for a .Net Int32 should be: NUMBER(9, 0)
As per the Conversion Table:
+------------------------------+------------------+-----------------+
| Oracle Type | Default EDM Type | Custom EDM Type |
+------------------------------+------------------+-----------------+
| Number(1,0) | Int16 | bool |
| Number(2,0) to Number(3,0) | Int16 | byte |
| Number(4,0) | Int16 | Int16 |
| Number(5,0) | Int16 | Int32 |
| Number(6,0) to Number(9,0) | Int32 | Int32 |
| Number(10,0) | Int32 | Int64 |
| Number(11,0) to Number(18,0) | Int64 | Int64 |
| Number(19,0) | Int64 | Decimal |
+------------------------------+------------------+-----------------+
Edit:
I found a way you can force the Number(2,0) to be translated to a byte in the App.Config for Database-First approach:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
</connectionStrings>
<oracle.dataaccess.client>
<settings>
<add name="bool" value="edmmapping number(1,0)" />
<add name="byte" value="edmmapping number(3,0)" />
<add name="int16" value="edmmapping number(4,0)" />
REF: https://docs.oracle.com/database/121/ODPNT/entityDataTypeMapping.htm#ODPNT8300
回答2:
The query
var order = testDbContext.Orders.FirstOrDefault(o => o.Status > 1);
is executed on the server so it returns the excepted result.
Then the Order entity is created and EF tries to map a value of ENTRY_STATUS column from number(2,0) to Int32 which is not possible.
In my point of view the best solution is to change a type of Status to Int16
[Column("ENTRY_STATUS")]
public Int16 Status { get; set; }
回答3:
It was a caching problem.
Following article helped me: http://codethug.com/2016/02/19/Entity-Framework-Cache-Busting/
I don't know if it is an EF bug that the query itself (o => o.Status > 1) recognizes the change in the database but than retrieves the data from the cache, which can be different.
Anyway, adding AsNoTracking() solved the problem:
var order = testDbContext.Orders.AsNoTracking().FirstOrDefault(o => o.Status > 1);
来源:https://stackoverflow.com/questions/46589929/oracle-db-to-ef-not-working-correctly-for-number2-0