Does C# have an enum that would match SQL object type? - sql

In the sys.objects table documentation, there's a list of types with their corresponding codes:
SO = Sequence object
U = Table (user-defined)
V = View
...
Is there a native enum or const in C# that would match these Sql object type?
The closest enum I've found is the DAC ObjectType Enum but it only matches some of the Sql object type.
Since SQL server is using 2 characters codes for these type, I understand that I would probably have write some mapping logic... but I'd prefer using a native enum instead of writing my own Enum.

Is there a native enum or const in C# that would match these Sql object type?
No. There is not.

Related

Structure where the data type of a member differs

Maybe superfluous, but some intro...
I am rewriting an add-in for my CAD-application (using VB.NET).
This add-in reads, via an API, a bunch of metadata from a file, presents it in a Form. This data can then be (partially) changed and written back to the file.
This metadata is accessible in a consistent way, however the data type is not the same everywhere (String, Currency, Date, Boolean, Long and IPictureDisp).
Currently I have a much too complex class with several arrays. I thought it might be smarter to create a structure. The problem is the varying data type.
Is it possible to define a structure with a member with varying datat type, or am I forced to define a different structure for each data type?
You have a few options...
1: Use Object
Nice and simple, every data type inherits from Object - so if your struct contains a property of type Object, you can put pretty much any data type in there
From the docs:
The Object data type can point to data of any data type, including any object instance your application recognizes. Use Object when you do not know at compile time what data type the variable might point to.
However, this does mean that you will get next to no help from the compiler when you are trying to write code using this property. You will also probably have to cast any time you need to do anything type-specific
2: Generic Types
This will not fit situations where you are not sure of the type. You can create a generic struct using the Of syntax.
You'd create it as so:
Structure MyStructure(Of T)
'our changing type
Dim MyCustomData As T
'...alongside regular types
Dim Name As String
Dim OtherThing As Integer
End Structure
and then when you need to create the structure, you'd simply pass the type in and assign the value
Dim struct As New MyStructure(Of Integer)
struct.MyCustomData = 123
Dim struct2 As New MyStructure(Of String)
struct2.MyCustomData = "a"

How to expose the return type of a global class method?

I've written an ABAP Method, which returns me some analyses in a custom table.
Now I want to call this Method from an RFC module.
So far so good - the method works fine, but I'm curious of how to return this table?
Do I have to create a table / structure ... in SE11 to make it work because otherwise I can't refer to this table type or is there an easier way?
I'm quite new to ABAP so I don't know the best practices.
m_analyses = new zcl_manalyses( ).
data(lt_m_analyses) = m_analyses->analyse_m_data(
budat_from = budat_from
budat_to = budat_to
).
The TYPES statement can not only occur inside a method's body, but also inside the class definition, in which case it can be accessed from other places with class_name=>type_name (if it's public):
CLASS cl_user_registry DEFINITION PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF user,
firstname TYPE string,
lastname TYPE string,
END OF user,
users TYPE STANDARD TABLE OF user.
METHODS:
get_current_users
RETURNING users.
ENDCLASS.
DATA current_users TYPE cl_user_registry=>users.
current_users = cl_user_registry=>get_current_users( ).
You first have to create a structure in ABAP Dictionary (SE11), then you create a table type in SE11 as well.
You then reference the structure in the line type of the table type.
Try using the new global table type, it should work. (with typing 'TYPE')

Hibernate SQL transformation fails for Enum field type

I am using a SQL query and then transforming the result using Hibernates's Transformers.aliasToBean().
One of the columns in my query is an enum. The transformation somehow fails for the enum. What should I do? Which datatype should I use? I want more than 1 character to transform the result into my enum type.
This is how the simplified version of my query/code looks like (b is an enum in the table profiles):
session.createSQLQuery("select a, b from profiles").setResultTransformer(Transformers.aliasToBean(Profile.class))
.list();
Exception : expected type: Foo.ProfileStateEnum, actual value: java.lang.Character
Assuming that the java enum type that corresponds to column b is Foo.ProfileStateEnum, the following code snippet should work for you. (I tested with Hibernate 4.1.6)
import java.util.Properties;
import org.hibernate.type.Type;
import org.hibernate.type.IntegerType;
import org.hibernate.internal.TypeLocatorImpl.TypeLocatorImpl;
import org.hibernate.type.TypeResolver.TypeResolver;
import org.hibernate.type.EnumType;
Properties params = new Properties();
params.put("enumClass", "Foo.ProfileStateEnum");
params.put("type", "12"); /*type 12 instructs to use the String representation of enum value*/
/*If you are using Hibernate 5.x then try:
params.put("useNamed", true);*/
Type myEnumType = new TypeLocatorImpl(new TypeResolver()).custom(EnumType.class, params);
List<Profile> profileList= getSession().createSQLQuery("select a as ID, b from profiles")
.addScalar("ID", IntegerType.INSTANCE)
.addScalar("b", myEnumType )
.setResultTransformer(Transformers.aliasToBean(Profile.class))
.list();
I found two ways to achieve it.
Use org.hibernate.type.CustomType with org.hibernate.type.EnumType(put either EnumType.NAMED or EnumType.TYPE, see EnumType#interpretParameters). Like below:
Properties parameters = new Properties();
parameters.put(EnumType.ENUM, MyEnum.class.getName());
// boolean or string type of true/false; declare database type
parameters.put(EnumType.NAMED, true);
// string only; declare database type
parameters.put(EnumType.TYPE, String.valueOf(Types.VARCHAR));
EnumType<MyEnum> enumType = new EnumType<>();
enumType.setTypeConfiguration(new TypeConfiguration());
enumType.setParameterValues(parameters);
CustomType customEnumType = new CustomType(enumType);
Another simple way. Use org.hibernate.type.StandardBasicTypeTemplate with org.hibernate.type.descriptor.sql.*TypeDescriptor. Like below:
StandardBasicTypeTemplate<MyEnum> enumType =
new StandardBasicTypeTemplate<>(VarcharTypeDescriptor.INSTANCE,
new EnumJavaTypeDescriptor<>(MyEnum.class));
Let's see why you are getting this exception.
From the question it is obvious that you have used #Enumerated(EnumType.STRING) annotation for the field 'b' in you model class. So the field is an enum for your model class and a varchar for your database. Native SQL is not concerned about you model class and returns what ever is there in the database table as it is. So in your case, the SQLQuery you are using will return a String for 'b' instead of a ProfileStateEnum type. But your setter method for 'b' in the Profile class takes a ProfileStateEnum type argument.
Thus you get the exception "expected type: Foo.ProfileStateEnum, actual value: java.lang.Character"
You can use Aliasing to solve the problem.
What I suggest is, alias your column with any name you want and create a setter method for that alias in your model/dto.
For example, lets alias your column as 'enumStr'.
Then your query will look like this : "select a, b as enumStr from profiles"
Now, create a setter method for that alias in the your Profile class.
(Assuming that the enum ProfileStateEnum can have any of the two values STATE1 and STATE2)
public void setEnumStr(String str){
/*Convert the string to enum and set the field 'b'*/
if(str.equals(ProfileStateEnum.STATE1.toString())){
b = ProfileStateEnum.STATE1;
} else {
b = ProfileStateEnum.STATE2;
}
}
Now on transforming, the setter for the alias setEnumStr(String) will be invoked instead of setter for the field setB(ProfileStateEnum) and the string will be converted and saved to the type you want without any exceptions.
I am a beginner in Hibernate and the solution worked for me. I am using PostgreSQL. But I believe it works for other databases too.

Determining if a type is a reference type or value type

I've come from a Assembler and C/C++ background, so I understand the concept behind reference types versus value types in vb.net. Also, I've read Jon Skeet's article regarding references and value types and I understand all of that.
My question is: How can you tell if a given type is a reference type or a value type?
Is it simply that all integral types (ints, floats, etc.) are value types and all classes are reference types? (If so, where do strings fall?)
Question 2 (related): Is there a way to declare a class as a value class versus a reference class? For example (using extreme brevity):
Public Class MyClass1
Public Value As Integer
End Class
Using this class:
Dim test1 As New MyClass1
test1.Value = 1
Dim test2 As MyClass1
test2 = test1
test2.Value = 2
At the end of this code, the Value in Test1 is 2. Clearly, MyClass1 is a reference type. But, what is it that causes it to be such and not a value type?
In general - enums and structs are value types, classes interfaces and delegates are reference types.
As for declaring a class as a value type - this is not possible, but C# structs are very close to classes and are value types.
As for VB.NET, I believe the equivalent is the Structure statement:
The Structure statement defines a composite value type that you can customize.

Restricting an NHibernate query using ICriteria according to an enumeration of enums

I have an entity, with a field of type enum, that is persisted as an integer in my database.
When retrieving objects from the database using ICriteria, I wish to restrict the results to those with the field being a member of a collection of enum values. Does Restrictions.In work with a collection of enums?
The following does not work. Do I have to perform something like type-casting at the "restrictions.in" part of the query?
var myEnumCollection = new MyEnum[] { MyEnum.One };
return FindAll<MyType>(Restrictions.In("EnumProperty", myEnumCollection));
FindAll is a method encapsulating
criteria.GetExecutableCriteria(Session).List<MyType>()
My initial guess would be that you'll need to compare against the integer values of the enum members (assuming that you're mapping the enum as an integer); so something like:
var myEnumCollection = new int[] { MyEnum.One };
return FindAll<MyType>(Restrictions.In("EnumProperty", myEnumCollection));
May be the solution that you're after. If you update your post with further details (mapping of the enum member and the sql being generated by the query), I may be able to provide further assistance.