Map sql out parameter to POGO - jdbc

I have groovy code like the following
query.call(sqlString, [Sql.out(OracleTypes.CURSOR)]) { ResultSet cursor ->
while (cursor.next()) {
println cursor.getString("whatever")
}
But what I want to be able to do, is to load the whole row into an object. Like in this example
sql.eachRow("Select * from Person") {
persons << new Person( it.toRowResult() )
}
How can I get from one to the other, given that I have to work through an Oracle Out parameter?

Related

Pushing empty DataTable into SQL Query as structured parameter

I recently bumped into an issue of raising an exception "Type structured needs to have at least one field" when pushing empty DataTable to an SQL query as structured parameter.
I basically have something like this (MyTestType is defined on the SQL server):
DataTable dt = new DataTable("test")
dt.Columns.Add("id", typeof(int));
try {
using(SQLConnection conn = new SQLConnection("{ConnectionString}"))
{
conn.Open();
using(SQLCommand comm = new SQLCommand("SELECT * FROM #TestDataTable", conn))
{
comm.Parameters.Add(new SQLParameter("#TestDataTable", SqlDbType.Structured){ Value = dt, TypeName = "dbo.MyTestType" });
using(SQLDataReader reader = comm.ExecuteReader())
{
while(reader.Read())
{
...
}
}
}
}
}
catch(Exception(ex))
{
throw(ex)
}
finally
{
conn.Close()
}
The thing is, I might end up with or without any data in my DataTable that I pass as a parameter into the query and the query really doesn't mind if the provided DataTable is empty, it just does some joins and if they equal to nothing, then nothing happens. Problem is that C# won't let it pass into the query and I really don't want to provide some "blank" DataRow in case it's empty just so it gets over it. That is not a clean solution.
Anyone any idea? Thanks in advance. PS: if the code has some issue, just quick fix it, I typed it from the top of my head.

what is a projection in LINQ, as in .Select()

I typically do mobile app development, which doesn't always have .Select. However, I've seen this used a bit, but I don't really know what it does or how it's doing whatever it does. It is anything like
from a in list select a // a.Property // new Thing { a.Property}
I'm asking because when I've seen code using .Select(), I was a bit confused by what it was doing.
.Select() is from method syntax for LINQ, select in your code from a in list select a is for query syntax. Both are same, query syntax compiles into method syntax.
You may see: Query Syntax and Method Syntax in LINQ (C#)
Projection:
Projection Operations - MSDN
Projection refers to the operation of transforming an object into a
new form that often consists only of those properties that will be
subsequently used. By using projection, you can construct a new type
that is built from each object. You can project a property and perform
a mathematical function on it. You can also project the original
object without changing it.
You may also see:
LINQ Projection
The process of transforming the results of a query is called
projection. You can project the results of a query after any filters
have been applied to change the type of the collection that is
returned.
Example from MSDN
List<string> words = new List<string>() { "an", "apple", "a", "day" };
var query = from word in words
select word.Substring(0, 1);
In the above example only first character from each string instance is selected / projected.
You can also select some fields from your collection and create an anonymous type or an instance of existing class, that process is called projection.
from a in list select new { ID = a.Id}
In the above code field Id is projected into an anonymous type ignoring other fields. Consider that your list has an object of type MyClass defined like:
class MyClass
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
}
Now you can project the Id and Name to an anonymous type like:
Query Syntax:
var result = from a in list
select new
{
ID = a.Id,
Name = a.Name,
};
Method Syntax
var result = list.Select(r => new { ID = r.Id, Name = r.Name });
You can also project result to a new class. Consider you have a class like:
class TemporaryHolderClass
{
public int Id { get; set; }
public string Name { get; set; }
}
Then you can do:
Query Syntax:
var result = from a in list
select new TemporaryHolderClass
{
Id = a.Id,
Name = a.Name,
};
Method Syntax:
var result = list.Select(r => new TemporaryHolderClass
{
Id = r.Id,
Name = r.Name
});
You can also project to the same class, provided you are not trying to project to classes generated/created for LINQ to SQL or Entity Framework.
My summary is it takes results (or a subset of results) and allows you to quickly restructure it for use in the local context.
The select clause produces the results of the query and specifies the
"shape" or type of each returned element. For example, you can specify
whether your results will consist of complete Customer objects, just
one member, a subset of members, or some completely different result
type based on a computation or new object creation.
Source: http://msdn.microsoft.com/en-us/library/bb397927.aspx
There are a lot of possible uses for this but one is taking a complex object which of many other contains a property that is a string -- say Name -- and allows you to return an enumeration with just the entries of Name. I believe you can also do the opposite -- use that property ( for example) and create / return new type of object while passing in a property or properties.
It means "mapping". Map each element of a sequence to a transformed sequence. I hadn't comprehended its meaning before I looked at the image.
Where does the meaning of the word come from?
Simply, math! https://mathworld.wolfram.com/Projection.html

How to return the result set with columns with Linq

I have a function inside a class that will run a Linq to Entities query (or any type of Linq query actually), and it's gonna return 2 columns in the resultset. I would like to return an object to whoever is calling my function that will allow Intellisense to know what I have returned.
Let me explain. If I have a function like this:
public static IQueryable GetInfo(MyEntityModel oEntityModel)
{
var query =
(from t in oEntityModel.Table1
from u in t.Table2
where t.Status == true &&
u.Status == true
select new
{
t.Column1,
u.Column2
})
return query;
}
What can (should) I put instead of IQueryable so that whoever calls my GetInfo function, will get Intellisense from the resultset, and show that it has a Column1 and Column2?
var linqresult = ClsLinqTeste.GetInfo(oEntityModel);
if (linqresult.Column1 == 1)
{
foreach (var oItem in linqresult)
{
.. do stuff...
}
}
Tks
You cannot return an anonymous type from a function, they are strictly "inline" classes. When you return it, the foreach loop will only be able to interpret the result as an plain object. I guess you could use reflection to query the property names and values, however it seems much more straight forward to define a data transfer type to hold the results.
See this question, and this blog post.
So you could create a simple struct or class:
public class MyDataResult
{
public object Column1 { get; set; }
public object Column2 { get; set; }
}
Then modify your query in the function:
public static IQueryable<MyDataResult> GetInfo(MyEntityModel oEntityModel)
{
var query =
(from t in oEntityModel.Table1
from u in t.Table2
where t.Status == true &&
u.Status == true
select new MyDataResult
{
Column1 = t.Column1,
Column2 = u.Column2
})
return query;
}
Something like that should work. Note that I used "object" for the properties in MyDataResult. I don't know the types of the columns you are returning, you should use the actual types in order to get full intellisense.
You are returning a collection of anonymous types, they will be casted to objects, so when you try to iterate over them, altough they will be your objects (and they will contain your properties) at compile time they will be casted to objects:
foreach (var x in ClsLinqTeste.GetInfo(oEntityModel))
{
//x is an Object
}
You can read more about it here.
If you want to have intellisense, I suggest you create a custom class they will hold your properties and return not an anonymous type (using new {}) but object of your class (new MyClass(prop1, prop2)). You also need to change signature of your method, so it returns IQueryable<YourClass> and not just plain non-generic IQueryable.
As others have said, creating a new type to hold the two columns is usually the best option.
But if, for some reason, you don't want to do that and you are using .Net 4.0, you can use Tuple:
public static IQueryable<Tuple<Column1Type, Column2Type>>
GetInfo(MyEntityModel oEntityModel)
{
return from …
select Tuple.Create(t.Column1, u.Column2);
}
var linqresult = ClsLinqTeste.GetInfo(oEntityModel);
foreach (var oItem in linqresult)
Console.WriteLIne(oItem.Item1, oItem.Item2);
When you return your resultset AsQueryable, the app is already able to give you intellisense, however in your example, you must specify either .FirstOrDefault if you know your collection will only have a single row, or iterate over your collection to get the items from it, like so:
This is what you're doing:
var linqresult = ClsLinqTeste.GetInfo(oEntityModel);
if (linqresult.Column1 == 1)
{
..do stuff...
}
This is how you should do it:
var linqresult = ClsLinqTeste.GetInfo(oEntityModel);
foreach(var item in linqresult)
{
if (item.Column1 == 1)
{
..do stuff...
}
}
You must iterate over linqresult because when you query with link, it returns a result set, even if it just has one column. As with any collection, your data columns aren't available on the whole result set, only with individual items.
If you want to strongly typed enumerate a non-generic IEnumerable (IEnumerable.GetEnumerator() instead of IEnumerable<T>.GetEnumerator<T>()) you can use the Cast<>() extension, like so
var myquery = GetQueryable();
for (var item in myquery.Cast<MyDataType>())
{
// use item.Column1 directly and strongly typed with intellisense
}

How to choose programmatically the column to be queried by Linq using PropertyInfo?

I would like to control how Linq queries my database programmatically. For instance, I'd like to query the column X, column Y, or column Z, depending on some conditions.
First of all, I've created an array of all the properties inside my class called myPropertyInfo.
Type MyType = (typeOf(MyClass));
PropertyInfo[] myPropertyInfo = myType.GetProperties(
BindingFlags.Public|BindingFlags.Instance);
The myPropertyInfo array allows me to access each property details (Name, propertyType, etc) through the index [i].
Now, how can I use the above information to control how Linq queries my DB?
Here's a sample of a query I'd like to exploit.
var myVar = from tp in db.MyClass
select tp.{expression};
Expression using myPropertyInfo[i] to choose which property (column) to query.
I'm not sure if that's the way of doing it, but if there's another way to do so, I'll be glad to learn.
EDIT:
I believe the right expression the one used by #Gabe. In fact, I'd like to make queries on the fly. Here's the reason: I've (i) a table Organizations (Ministries, Embassies, International Organizations, such as UN, UNPD, UNICEF, World Bank, etc, and services depending on them). I've (ii) an other table Hierarchy which represents the way those organizations are linked, starting by which category each one belongs to (Government, Foreign Missions, private sector, NGO, etc.)
Each column representing a level in the hierarchy, some rows will be longer while other will be shorter. Many rows' columns will share the same value (for instance 2 ministries belonging to the government, will have "Government" as value for the column 'Level 1').
That's why, for each row (organization), I need to go level by level (i.e. column by column).
if you're using Entity Framework, not LINQ to SQL, there is wonderful Entity Sql
and you can use it as
object DynamicQuery(string fieldName, object fieldValue) {
string eSql=string.Format("it.{0} = #param", fieldName);
return db.Where(eSql, fieldValue).FirstOrDefault();
}
hope this helps
MSDN has the following example, you see that you can dynamicly change strings used to access ProductID field, and as far as i remember event rename it.
using (AdventureWorksEntities advWorksContext =
new AdventureWorksEntities())
{
try
{
// Use the Select method to define the projection.
ObjectQuery<DbDataRecord> query =
advWorksContext.Product.Select("it.ProductID, it.Name");
// Iterate through the collection of data rows.
foreach (DbDataRecord rec in query)
{
Console.WriteLine("ID {0}; Name {1}", rec[0], rec[1]);
}
}
catch (EntitySqlException ex)
{
Console.WriteLine(ex.ToString());
}
}
Also you can even do the following (again from MSDN)
using (AdventureWorksEntities advWorksContext =
new AdventureWorksEntities())
{
string myQuery = #"SELECT p.ProductID, p.Name FROM
AdventureWorksEntities.Product as p";
try
{
foreach (DbDataRecord rec in
new ObjectQuery<DbDataRecord>(myQuery, advWorksContext))
{
Console.WriteLine("ID {0}; Name {1}", rec[0], rec[1]);
}
}
catch (EntityException ex)
{
Console.WriteLine(ex.ToString());
}
catch (InvalidOperationException ex)
{
Console.WriteLine(ex.ToString());
}
}
It sounds like you want to make a Queryable on-the-fly. I haven't tried it, but this might give you a start:
var myVar =
Queryable.Select(
db.MyClass,
Expression.Property(
Expression.Parameter(
typeof(MyClass), // this represents the type of "tp"
"tp"
),
myPropertyInfo[i]
)
)

How to query Anonymous Type collection?

How do you query a collection which is populated/created with select new?
I have this BindingSource:
this.bindingSource.DataSource =
from row in db.Table
select new
{
name = row.Name + row.Num.ToString()
};
I'd like to query it like I do with other BindingSources:
var query = from row in (IEnumerable<Table>)anotherBindingSource.List
where row.name == "asd"
select row;
Since bindingSource contains anonymous types I get this error:
Unable to cast object of type
'System.Data.Linq.SortableBindingList1[<>f__AnonymousType815
etc. etc. to type 'System.Collections.Generic.IEnumerable`1[Table]'.
What should I do?
Well, not sure exactly what you're trying to do here, but an anonymous type != a Table object. The exception indicates you're trying to cast an IEnum of an anonymous type (a compiler-generated class with a weird name) to an IEnum of type Table.
You can't cast types willy nilly in C#. You can't, for instance, do this:
(Table)"Lol I'd like to be a table pls kthx"
You can't cast any type that isn't already a Table, or extends from Table, to a Table.
So what you're asking is impossible. You should probably take a step back and ask a more general question about what you're trying to accomplish.
Some more on anon types... They only really have meaning within the scope of the method in which they are defined. It appears you might be returning your anon type enumeration from a method call and then are attempting to sort. This won't work, as once the anonymous type leaves the method scope it is considered (at least by intellisense) to be an object and the only way to get at its properties is to use reflection.
If your example isn't just a simplified version, you could just skip the anon type altogether...
this.bindingSource.DataSource =
from row in db.Table
select row.Name + row.Num.ToString();
This is an IEnumerable, and can be queried thusly:
var query = from row in anotherBindingSource
where row.StartsWith("asd")
select row;
However it doesn't look like you're accomplishing much at all with this...
You cannot query anonymous types outside of the scope in which they are defined.
This works:
public void Worthless(Hurr hurr)
{
var query = from x in hurr select new { x.Durr };
var requery = from x in query where x.Durr == "lol" select x;
}
This does not:
public class Anonymous
{
public IEnumerable GetMyDurrs(Hurr hurr)
{
return from x in Hurr select new { x.Durr };
}
public IEnumerable WeedMyDurrs(Hurr hurr, string value)
{
// this won't compile
return from x in GetMyDurrs(hurr) where x.Durr == value select x;
}
}
The second example won't compile because the anonymous type was defined within another scope.
The only way to get this to work is to define a type.
public class Anonymous
{
public IEnumerable<Anonymous.MyDurr> GetMyDurrs(Hurr hurr)
{
return from x in Hurr select new MyDurr { Durr = x.Durr };
}
public IEnumerable<Anonymous.MyDurr> WeedMyDurrs(Hurr hurr, string value)
{
// this won't compile
return from x in GetMyDurrs(hurr) where x.Durr == value select x;
}
public class MyDurr { public string Durr {get;set;} }
}

Resources