views:

141

answers:

2

I am investigating the use of Entity Framework in my organization. We use Oracle DBMS, and therefore (for good or ill) are using the "pseudo-boolean" pattern common in Oracle where instead of having a boolean column (which doesn't exist in Oracle) you have a 1 character column with a check constraint to force it to "Y" or "N".

So, if I want an entity in my EF model to have a boolean property, how do I map this to a database column as "Y" for true and "N" for false? Is there a concept of "Converters" or something in Entity Framework that will do this for me?

And just because it will probably come up, I know that EF only works with SQL Server out of the box. I would be using the DevArt dotConnect for Oracle to use EF with Oracle.
http://www.devart.com/dotconnect/oracle/

Edit
What about other ORM frameworks like NHibernate? Do they handle this scenario "out of the box"?

+1  A: 

Devart dotConnect for Oracle has automatic mapping of the NUMBER(1) column to the System.Boolean, it simplifies the work with these columns - 0 corresponds to false, non-zero(1 by default) - to true. No additional actions are needed.
In case you wish to keep boolean values in the char form then you have to choose one of the following approaches:
1. Leave the string type for the property mapped to the character column. Add an additional wrapper property of boolean type to the partial entity class and convert the string value to boolean and vice versa in getter and setter accordingly.
Disadvantage: This wrapper property cannot be used in LINQ to Entities.
2. Create a view over your table that will return 0 or 1 instead of values from your character column. As an alternative, create a DefiningQuery in the model for this EntitySet(it shouldn't be added to database in this case). In most cases there will be need to change the type for the property from "char(1)" to "bool" in SSDL and from System.String to System.Boolean in CSDL. You should write a set of stored procedures to execute CUD operations with your entity and map these procedures for this entity to be updatable.
Disadvantage: A lot of work.

Devart
Thanks for the response. I considered both of these options but was hoping to find a way to get the same treatment for NUMBER(1) as for VARCHAR(1). The disadvantages of these options are significant for us. And we can't really change to using NUMBER(1) we have 100s of tables using the VARCHAR(1) method.
jkohlhepp
+1  A: 

At resent, there is no official EDM-EF mapping from Oracle - DevArt and DataDirect both have custom Oracle connection provider layers that you can buy. There's also the quasi-opensource versions available at CodeProject that implement EDM for EF w/ Oracle. I presume that you are using one of these.

To address your question though, what you need is to alter the ProviderManifest implementation to return the appropriate .NET type in the call to GetEdmType(). The problem is that this method passes you an Oracle type and expects you to return a .NET type that EF understands (it understands all primitives, including bool). Unfortunately, it isn't desirable to map CHAR(1) to Boolean, as you could in principle have other CHAR(1) columns that are not bools.

The workaround to this problem is to create an oracle user-defined type (JKBOOL, lets say :), that is mapped to CHAR(1) - you would then have to alter your tables to change CHAR(1) to JKBOOL. Now you can safely map JKBOOL to System.Boolean in GetEdmType().

LBushkin
Interesting stuff, but if I'm going to create a user-defined type in Oracle and use that instead of CHAR(1) I might as well just use NUMBER(1) to represent bools which DevArt's EF provider already maps correctly to bools.
jkohlhepp
The difference is that the UDT can still be treated as a `CHAR(1)` by any SQL or PLSQL code - because the UDT is just an alias for that type. Changing the column to a `NUMBER` would be a breaking change and require analysis of which queries, packages, and views would be affected.
LBushkin
Ah. Now I see what you're saying. I will definitely look into this possibility. Thanks for the info.
jkohlhepp
I've searched online but am having a hard time finding any working examples of how to properly override/implement `GetEdmType` for a particular database type. I'm in a similar situation as that with Oracle, as I have a lot of informix columns declared as `CHAR(1)` when they really represent boolean values. Tapping into `GetEdmType()` appears to be the correct way to approach, I just can't find examples.
kdawg