EF Core Value Converter In Oracle Wont Work - oracle

i use Ef core and Oracle
i have a Column in Oracle Database With Data Type NVARCHAR2(20)
but in my Class Model i want Convert It Decimal
this is Config For ValueConverter :
entity.Property(e => e.ColumnName)
.HasMaxLength(20)
.HasColumnType("NVARCHAR2(20)")
.HasColumnName("COLUMN_NAME")
.HasConversion(
v => v.ToString(),
v => v=="" ? 0 : decimal.Parse(v, NumberStyles.Any, CultureInfo.InvariantCulture));
and this my My Model :
public decimal? ColumnName{ get; set; }
but after use this query this error show :
ORA-00932: inconsistent datatypes: expected NUMBER got NCHAR'

I Convert Column Via Oracle Query with check for number combability
(case when REGEXP_LIKE(ColumnName, '^[[:digit:]]+$') then to_number(ColumnName) else 0 end) as ColumnName

Related

Exception whilst querying decimal fields in Apache Drill

I am trying to run the following query in apache drill. I am querying data stored in parquet files using the following query
select
pan, count(*) as number_of_transactions,
terminal_id,
sum((cast(SETTLE_AMOUNT_IMPACT as double) * -1) / 100) as settle_amount_impact
from
dfs.`/iswdata/storage/products/superswitch/parquet/transactions`
where
pan like '506126%'
and terminal_id like '1%'
and sink_node_name like ('SWTDB%')
and source_node_name not like ('SWTDBLsrc')
and tran_completed = 1
and tran_reversed = 0
and tran_postilion_originated = 1
and tran_type = '01'
--and pan like '506126%0011'
group by
pan, terminal_id
The schema for the data I am querying is as follows
post_tran_id LONG 2
post_tran_cust_id :LONG
settle_entity_id :INTEGER
batch_nr : INTEGER
prev_post_tran_id : LONG
next_post_tran_id : LONG
sink_node_name : STRING
tran_postilion_originated : DECIMAL
tran_completed : DECIMAL
tran_amount_req : DECIMAL
tran_amount_rsp : DECIMAL
settle_amount_impact : DECIMAL
tran_cash_req : DECIMAL
tran_cash_rsp : DECIMAL
tran_currency_code : STRING
tran_tran_fee_req : DECIMAL
tran_tran_fee_rsp : DECIMAL
tran_tran_fee_currency_code : STRING
tran_proc_fee_req : DECIMAL
tran_proc_fee_rsp : DECIMAL
tran_proc_fee_currency_code : STRING
settle_amount_req : DECIMAL
settle_amount_rsp : DECIMAL
settle_cash_req : DECIMAL
settle_cash_rsp : DECIMAL
settle_tran_fee_req : DECIMAL
settle_tran_fee_rsp : DECIMAL
settle_proc_fee_req : DECIMAL
settle_proc_fee_rsp : DECIMAL
settle_currency_code : STRING
However When I run the query against the dataset, I get the following exception
SYSTEM ERROR: ClassCastException: org.apache.drill.exec.vector.NullableDecimal28SparseVector cannot be cast to org.apache.drill.exec.vector.VariableWidthVector
More so, the same error occurs when I include a decimal field in the select clause.
Please, is there something I am missing or doing wrong, Any pointer will be deeply appreciated
Kind Regards
Decimal values in parquet table are stored using BINARY primitive type, but currently, Drill does not support decimals stored as binary.
It will be fixed in DRILL-6094 and it will be available in 1.14 release.

Bltoolkit oracle clob type

I use bltoolkit as orm and i had a problem with clob type.
I have a long string value and i got error while update operation.
Error: ORA01704 - String literal too long.
Checked table and my column type is clob.
There is no clob option in bltoolkit table class design.
I set this column like that:
[MapField("MSG_BODY")]
public string MsgBody { get; set; }
What is wrong ?
I find a solution, post only clob columns and it works !
//update only body
value = db.Schedule
.Where(x => x.Rowversion == _zaman
&& x.ScheduleId == this.ScheduleId)
.Set(x => x.Rowversion, x => _zaman)
.Set(x => x.MsgBody, x => this.MsgBody)
.Update();

Entity Framework Pagination (Select records using string datetime column)

I have a table which has startdate (in format "yyyymmddhhss")and the corresponding entity attribute is string type. I would like to use LINQ To SQL get all the records with StartDate >= SelectedStartDate. Since this table has more than 10 million records, I need to use pagination as well.
Could anyone please suggest on how to implement this/
Regards,
Raaj
The best solution would be of course to migrate the string values to a DATETIME column and query the data from that column.
But if you don't have enough privileges to do that, you're lucky you have the format yyyymmddhhss in your table because that preserves the natural order of dates; all you have to do is to convert the parameter to a string in the required format:
public IEnumerable<YourDataObject> GetData(DateTime date, PageInfo pageInfo)
{
var startDate = date.ToString("yyyyMMddHHss");
return _dbContext.Table
.OrderBy(x => x.StartDate)
.Where(x => String.Compare(x.StartDate, startDate) >= 1)
.Skip(pageInfo.PageSize * pageInfo.PageIndex)
.Take(pageInfo.PageSize)
.Select(x => new YourDataObject
{
//
});
}
Here is a sample output in LINQPad:

comparing "string" and "null" in linq to entity

My code:
string name;
db.Entities.Where(m=>m.name==(name??m.name))
throw:Should be CHAR, but get NCLOB.
//----------------
decimal? id;
db.Entities.Where(m=>m.id==(id??m.id))
The code is working.
my database is oracle.
What should I do to make the code working.?
Thanks.
Beware that in Oracle an empty string is NULL.
I don't know about Oracle + EF and type mappings. But this is not the way to make predicates optional anyway, because now the part x ?? x.y will always be part of the expression that is translated into SQL. This may hit query optimization and performance.
The way to do this is:
IQueryable<Entity> query = db.Entities;
if (!string.IsNullOrWhiteSpace(name))
{
query = query.Where(m => m.Name == name);
}

How to convert a string into a datetime in Linq to Entities query?

My Linq to entities query is written as below.
The datatype of DATECOLUMN1 in my ORACLE database is of string.
Datetime FilterStartDate = DateTime.Now;
var query = from c in db.TABLE1
join l in db.TABLE2 on c.FK equals l.PK
where (FilterStartDate >= DateTime.ParseExact(l.DATECOLUMN1, "dd/MM/yyyy", CultureInfo.InvariantCulture) : false) == true
select c;
Writing above query gives me an error of not supported. How can I convert DATECOLUMN1 into a datetime to compare it.
P.S. I do not have control over database schema, so changing datatype of column in Oracle database is not a feasible solution for me.
In you Model, add the following property to your partial class TABLE2:
public DateTime DATECOLUMN1_NEW
{
get
{
return DateTime.ParseExact(DATECOLUMN1, "dd/MM/yyyy", CultureInfo.InvariantCulture);
}
set { }
}
Then, in you LINQ query, use DATECOLUMN1_NEW (it's already in DateTime format) in place of DATECOLUMN1.
Erm.. I think the problem you are having is that you are putting ": false" in there.
It looks like you are trying to use a condtional operator (?:) but you forgot the "?".
I don't think you actually need this as you are just trying to determine if the date is greater or not. Also if ParseExact fails it will throw an exception (not what you want) so you should use TryParse instead and handle the true/false returned and the out value to determine whether or not the date is (a) Actually a date (b) less then FilterStartDate.
You can use two alternatives:
Use the function described in the answer here: How to I use TryParse in a linq query of xml data?
Use the following fluent syntax version which I think is more readable.
var query = db.Table1.Join(db.Table2, x => x.FK, y => y.PK, (x, y) => x).Where(x =>
{
DateTime Result;
DateTime.TryParse(x.Date, out Result);
return DateTime.TryParse(x.Date, out Result) && FilterStartDate >= Result;
});

Resources