SubSonic How to Execute a SQL Statement? - subsonic

My site is using Subsonic 2.2 on my site.
I have 1 weird situation where I need to run some ad-hoc SQL statements.
public IList<string> GetDistincList(string TableName, string FieldName)
{
string sqlToRun = string.Format("SELECT DISTINCT {0} FROM {1} ORDER BY {0}", FieldName, TableName);
Query query = new Query(TableName);
query.PleaseRunThis(sqlToRun);
query.ExecuteReader();
}
Can anyone help me here? As it appears, I just want to return a generic list of strings.
Thanks!

Subsonic has a great method called ExecuteTypedList() so you can do somethink like this.
List<int> result = DB.Select(Table.Columns.Id)
.Distinct()
.From<Table>()
.OrderBy(Table.Columns.Id)
.ExecuteTypedList<int>();
or even with pocos:
public class UserResult
{
public int Id {get;set;}
public string Name {get;set;}
}
List<UserResult> users = DB.Select(
User.Columns.UserId + " as Id", // the as ... is only needed if your
User.Columns.UserName + " as Name" // column name differs from the
).From<User>() // property name of your class
.ExecuteTypedList<UserResult>();
Unfortunately this method doesn't work for string since it requires
a) a valuetype
b) a class with a parameterless constructor since the method uses reflection to map the columns from the result to the properties of the class
However I wrote an extension method a while ago that works for string:
Use the Subsonic.Select() ExecuteTypedList Method with String
Look at my own answer in the link.
If you add the extensionmethod to your code you can do:
List<String> result = DB.Select(User.Columns.UserName)
.From<User>()
.ExecuteTypedList();

Use the CodingHorror class.
Here's the SubSonic 3 way of doing it: http://www.subsonicproject.com/docs/CodingHorror
The SubSonic 2 way is similar:
Dim ch As SubSonic.CodingHorror
ch.Execute("delete from #tablename", table)

Related

Hazelcast - query collections of Map values

Assume I have the following as the value in an IMap:
public class Employee{
public int empId;
public List<String> categories;
public List<String> getCategories(){
return this.categories;
}
}
I would like to find all employees that belong to category "Sales". Also, I would like to create an index on getCategories() so that the query returns fast. There seems to be no Predicate available to do this. How do I go about achieving this? It seems like I will have to write a Predicate to do this. Is there example code I can look at that would show me how to build a predicate that uses an index ?
The only way I currently see this happening is to denormalize the data model and use something like a IMap and the following as value:
class EmployeeCategory{int employeeId, String category}
And put an index on category.
It is somewhere on the backlog to provide more advances indices that should be able to do this out of the box.
I tried by iterating the List to a separate Imap and then querying it in the client.
IMap<String,ArrayList< categories >> cache=hazelcastInstance.getMap("cache");
IMap<String, categories> cachemodified = hazelcastInstance.getMap("cachemodified") ;
int[] idx = { 0 };
xref.get("urkey").forEach(cachefelement ->{
cachemodified.put(String.valueOf(idx[0]++),cachefelement);
});
Predicate p = Predicates.equal("categoryId", "SearchValue");
Collection<categories> result = cachemodified.values(p);

How to assign all matching properties from Groovy object to Java object?

I want to use Groovy with JDBC to load some data from a table. I then want to copy the properties across where the property names match. How can I do this in Groovy?
Something like this:
sql.eachRow("select * from temp_table") {
def e = new MyJavaClass()
// copy matching fields from it to e
}
In addition to topchef's answer, you might be able to use some groovy map magic
If you limit your sql to the properties in your Java Class (and assuming you can hold the entire result in memory at once), then you should be able to use the rows method to get a List of GroovyRowResult objects (one per row). As this class is an instance of Map, groovy will use it to construct your java object automatically for you:
class MyJavaClass {
String property1, property2, property3
}
sql.rows("select property1, property2, property3 from temp_table").each { row ->
MyJavaClass e = row
}
Some groovy magic helps:
def filtered = ['property1', 'property2', ....]
sql.eachRow("select * from temp_table") {
def e = new MyJavaClass(it.properties.findAll{filtered.contains(it.key)})
}
Given that
list filtered contains all property names that you intend to copy;
your table column names correspond to MyJavaClass declared property names (the same as in the list filtered);
MyJavaClass has both default (empty) constructor and constructor
that takes all properties as parameters;
MyJavaClass declares public setters for properties;
E.g:
public MyJavaClass() {}
public MyJavaClass(String property1, String property2, ....) {
this.property1 = property1;
this.property2 = property2;
.... }
public void setProperty1(String property1) {this.property1 = property1;}
public void setProperty2(String property2) {this.property2 = property2;}
....
You may use filtered as a list of undesired properties like this:
def filtered = ['class', 'metaClass', ....]
then:
def e = new MyJavaClass(it.properties.findAll{!filtered.contains(it.key)})

Automapper: Mapping a property value of an object to a string

Using Automapper, how do you handle the mapping of a property value on an object to an instance of a string. Basically I have a list of Role objects and I want to use Automapper to map the content of each "name" property to a corresponding list of string (so I just end up with a list of strings). I'm sure it has an obvious answer, but I can't find the mapping that I need to add to "CreateMap" to get it to work.
An example of the relevant code is shown below:
public class Role
{
public Guid Id{get;set;}
public string Name{get;set;}
...
...
}
// What goes in here?
Mapper.CreateMap<Role, string>().ForMember(....);
var allRoles = Mapper.Map<IList<Role>, IList<string>>(roles);
I love Automapper (and use it in a number of projects), but wouldn't this be easier with a simple LINQ statement?
var allRoles = from r in roles select r.Name
The AutoMapper way of accomplishing this:
Mapper.CreateMap<Role, String>().ConvertUsing(r => r.Name);

Subsonic 3 - Sequence contains no matching element

I need help creating a LINQ SQL with subsonic. First the basics, this works fine:
var query = (from o in bd.concelhos
orderby o.descricao
select o);
var results = query.ToList<concelhos>();
However, I want to filter out some columns and I have created the following code:
var query = (from o in bd.concelhos
orderby o.descricao
select new FilteredConcelhos { id = o.idDistrito + "/" + o.idConcelho, descricao = o.descricao });
var results = query.ToList<FilteredConcelhos>();
which errors out in the ToList method with the description "Sequence contains no matching element"
Any help would be great with this...
update:
Turns out I was missing get set attributes in the newly declared class...
Like so
public class FilteredConcelhos
{
public string id { get; set; }
public string descricao { get; set; }
}
This clears the exception, but the resulting List is still all wrong (FilteredConcelhos.id contains nothing and FilteredConcelhos.descricao contains numbers)
Can you try to first execute the ToList and the select afterwards - then the select is performed via linq 2 objects!
Have you tried to work with an anonymous type?
var query = (from o in bd.concelhos
orderby o.descricao
select new { id = o.idDistrito + "/" + o.idConcelho,
descricao = o.descricao });
var results = query.ToList();
Unfortunately, this happened to me a lot. I'm not sure about the details of how Linq 2 Object works, but if you'll call ToList on the original object, like this:
from o in bd.concelhos.ToList()
...
It should do the trick.

What is the correct way to format SPGridView values being displayed?

Problem
As we know, SharePoint saves data in database in plain text. Some fields even have concatenated strings like <id>;#<value> for user fields. Percents are saved as doubles (1.00000000000000 for 100%) and etc.
Ofcourse, I want to display data as they are displayed in lists.
What should I do?
Should I use derived SPBoundField to format values (Which I actually did and it works fine until you want to filter (probably SPBoundField won't format me values because i use ObjectDataSource not list and with reflector I saw if there are SPListItems in datasource, then it formats correctly. Not my case)
alt text http://img199.imageshack.us/img199/2797/ss20090820110331.png
Or must I loop through all the DataTable and format each row accordingly?
What are Your techniques?
Thank you.
Here is how I solved this issue.
<asp:TemplateField HeaderText="Campaign Members">
<ItemTemplate>
<%# RemoveCharacters(Eval("CampaignMembers").ToString())%>
</ItemTemplate>
</asp:TemplateField>
// Make sure declare using System.Text.RegularExpression;
protected string RemoveCharacters(object String)
{
string s1 = String.ToString();
string newString = Regex.Replace(s1, #"#[\d-];", string.Empty);
newString = Regex.Replace(newString, "#", " ");
return newString.ToString();
}
I normaly use ItemTemplates that inherit from ITemplate. With in the ItemTemplate I use the SPFieldxxxValue classes or some custom formating code. This saves looping through the DataTable and the ItemTemplates can be reused.
The ItemTemplates are attached in Column Binding
E.G
// Normal Data Binding
SPBoundField fld = new SPBoundField();
fld.HeaderText = field.DisplayName;
fld.DataField = field.InternalName;
fld.SortExpression = field.InternalName;
grid.Columns.Add(fld);
// ItemTemplate Binding
TemplateField fld = new TemplateField();
fld.HeaderText = field.DisplayName;
fld.ItemTemplate = new CustomItemTemplateClass(field.InternalName);
fld.SortExpression = field.InternalName;
grid.Columns.Add(fld);
An example of a ItemTemplate
public class CustomItemTemplateClass : ITemplate
{
private string FieldName
{ get; set; }
public CustomItemTemplateClass(string fieldName, string formatString)
{
FieldName = fieldName;
}
#region ITemplate Members
public void InstantiateIn(Control container)
{
Literal lit = new Literal();
lit.DataBinding += new EventHandler(lit_DataBinding);
container.Controls.Add(lit);
}
#endregion
void lit_DataBinding(object sender, EventArgs e)
{
Literal lit = (Literal)sender;
SPGridViewRow container = (SPGridViewRow)lit.NamingContainer;
string fieldValue = ((DataRowView)container.DataItem)[FieldName].ToString();
//Prosses Filed value here
SPFieldLookupValue lookupValue = new SPFieldLookupValue(fieldValue);
//Display new value
lit.Text = lookupValue.LookupValue;
}
}
Here are a few options. I don't know the output of all of them (would be a good blog post) but one of them should do what you want:
SPListItem.GetFormattedValue()
SPField.GetFieldValue()
SPField.GetFieldValueAsHtml()
SPField.GetFieldValueAsText()
It may also be handy to know that if you ever want to make use of the raw values then have a look at the SPField*XYZ*Value classes. For example the form <id>;#<value> you mention is represented by the class SPFieldUserValue. You can pass the raw text to its constructor and extract the ID, value, and most usefully User very easily.
I would suggest either to format the values before binding them to the spgridview. Linq and an anonymous type is preffered or to call a code behind function on the field that needs the formatting upon binding.
DataField='<%# FormatUserField(Eval("UserFieldName")) %>'
or...maybe a templated field?
After all, i did have not know any other solution to loop through DataTable rows and format them accordingly.
If your SPGridView's data source is list, try out SPBoundField.

Resources