I am trying to sort a list of products by their name in a .Net application written in C#, to obtain the same list that I would get from an SQL Server database through an order by:
select * from Products order by ProductName
Unfortunately, the application sorting behaves differently than the database sorting. It is probably related to the collation: the database has an SQL_Latin1_General_CP1_CI_AS collation.
How can I make the application sort these strings exactly like the database does?
Thanks.
UPDATE: I finally obtained a good result by using the code from the comments below, and changing the compare options to Ordinal:
private CompareOptions myOptions = CompareOptions.Ordinal ;
Also, this link contains some very useful information related to SQL collations: http://www.siao2.com/2005/11/08/490305.aspx
Thanks. It does not work yet, but this is probably the right direction.
Here is the code I am trying now:
((List)orderDetails).Sort(new OrderDetailComparer());
where OrderDetailComparer is:
public class OrderDetailComparer : IComparer<OrderDetail>
{
private CompareInfo myComp = CompareInfo.GetCompareInfo("en-US");
private CompareOptions myOptions = CompareOptions.StringSort;
public int Compare(OrderDetail a, OrderDetail b)
{
if (a == b) return 0;
if (a == null) return -1;
if (b == null) return 1;
return myComp.Compare ( a.Product.ProductNameForSorting, b.Product.ProductNameForSorting, myOptions );
}
}
Still no result.
What do you think? How do I get the information from the database, to know what culture I should use?
Thanks.
you'll probably need to use the culture you wish to sort in. Look at the example of the StringComparer:
http://msdn.microsoft.com/en-us/library/system.stringcomparer.currentculture.aspx
Related
In a Table data, I have to remove these [*,=,#,&,^,%] from table data. I should not remove these
special characters [(,),/,.,#,',",:-,_,,\] while moving data from mssql to mysql using pentaho data
integration
example:-
Gujarat is the country’s largest castor oil seed producing state. The m*ajor
month’s
Why not use regular expressions in the query you are using to retrieve the data? It will simplify your transformation!
You can use either Regex Evaluation step or String operations step in Spoon
Try them and if you still have problems comment below.
You can use a "User Defined Java Class" in Pentaho and write a regex expression with the replace function.
public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws KettleException{
Object[] r = getRow();
if (r == null) {
setOutputDone();
return false;
}
if (first)
{
first = false;
}
r = createOutputRow(r, 1);
if(get(Fields.In, "data").getString(r) != null)
{
String output= get(Fields.In, "data").getString(r);
output= output.replaceAll("[^a-zA-Z0-9\\s()/\\.#-_]+","");
get(Fields.Out, "output").setValue(r, output);
}else {
get(Fields.Out, "output").setValue(r, "");
}
putRow(data.outputRowMeta, r);
return true;
}
data is the input stream data and the cleaned output would be in "output" column. I have shared a sample code here.
Hope this will solve your issue. :)
Modifying my earlier answer to include the full code. Having said this, i have also created a plugin recently to handle special characters. You can have a look at my blog site :
Blog link: https://anotherreeshu.wordpress.com/2015/01/07/special-character-remover-clean-your-data-of-special-characters-pentaho-kettle-step-plugin/
Even though its only version 1.0.0, but you can have a try. It might also help ypu :)
I have a WPF application which is displaying field validation messages by implementing the IDataErrorInfo interface. This is all working well.
What I want to do now is to break out the validation messages into an separate xml file so that validation message key value pairs can be stored outside of the code and can be easily maintained possibly by an end (super)user.
I was thinking of having a method something like:
private void ValidateRequiredField<T>(ref T field, string fieldName)
{
string error = null;
if (Equals(field, null)
|| (field is string
&& (string.IsNullOrEmpty(field.ToString())
|| field.ToString().Replace(" ", string.Empty).Length == 0)
)
|| (field is int
&& int.Parse(field.ToString()) == 0)
)
{
error = GetValueFromConfig(fieldName);
}
SetFieldDataError(fieldName, error);
}
Is the best way to store these key value pairs in an xml file? I seem to remember that there used to be a Microsoft Configuration Application Block but I can't see an equivalent in Enterprise Library 5.0. Is there a better way?
For anyone who may be pondering the same question...after much deliberating, I opted to use the Microsoft Enterprise Library 5.0
I've got this code (Java, GAE):
// Much earlier:
playerKey = KeyFactory.keyToString(somePlayer.key);
// Then, later...
PersistenceManager pm = assassin.PMF.get().getPersistenceManager();
Key targetKey = KeyFactory.stringToKey(playerKey);
Query query = pm.newQuery(Player.class);
query.setFilter("__key__ == keyParam");
query.declareParameters("com.google.appengine.api.datastore.Key keyParam");
List<Player> players = (List<Player>) query.execute(targetKey); // <-- line 200
which generates this error:
javax.jdo.JDOFatalUserException: Unexpected expression type while parsing query. Are you certain that a field named __key__ exists on your object?
at org.datanucleus.jdo.NucleusJDOHelper.getJDOExceptionForNucleusException(NucleusJDOHelper.java:354)
at org.datanucleus.jdo.JDOQuery.execute(JDOQuery.java:252)
at myapp.Player.validPlayerWithKey(Player.java:200)
// [etc., snip]
But I'm not sure what it wants. I'm trying to search on the JDO id field, which I I thought I read had the special name __key__, in the documentation.
I've tried it with both
query.setFilter("__key__ == keyParam");
and
query.setFilter("ID == keyParam");
with the same results. So, what am I doing wrong? Or, more importantly, how do I do it correctly?
Thanks!
Edit: For completeness's sake, here is the final, working code (based on Gordon's answer, which I have accepted as correct):
Player result = null;
if (playerKey == null)
{
log.log(Level.WARNING, "Tried to find player with null key.");
}
else
{
PersistenceManager pm = assassin.PMF.get().getPersistenceManager();
try {
result = (Player) pm.getObjectById(Player.class, playerKey);
} catch (javax.jdo.JDOObjectNotFoundException notFound) {
// Player not found; we will return null.
result = null;
}
pm.close();
}
return result;
If your objective is to get an object by key, then you should use the PersistenceManager's getObjectByID() method. More details here.
As an aside, trying to construct a query to get something by it's key is something you shouldn't need to do. Although this is how you would work with an SQL database, the Google Data Store does things differently, and this is one of those cases where rather than go through the trouble of constructing a query, Google App Engine lets you get what you want directly. After all, you should only have one entity in the database with a particular key, so there's nothing in the rest of the machinery of a GQL query that you need in this case, hence it can all be skipped for efficiency.
I would recommend you to use the JPA ( http://code.google.com/appengine/docs/java/datastore/usingjpa.html ) to access your data in GAE, it has the very important advantage that you can use the widely known and documented JPA standard (and its JPAQL querying language) to do this kind of things, in portable way (if you stick to the JPA standard, your code will work for GAE, for Hibernate or with EclipseLink without modification)
I'm using NHibernate 2.1.2.4000GA. I'm trying to use SQL Server's CONTAINS function from within HQL and the criteria APIs. This works fine in HQL:
CONTAINS(:value)
However, I need to qualify the table in question. This works fine:
CONTAINS(table.Column, :value)
However, I need to search across all indexed columns in my table. I tried this:
CONTAINS(table.*, :value)
But I get:
NHibernate.Hql.Ast.ANTLR.QuerySyntaxException : Exception of type 'Antlr.Runtime.MissingTokenException' was thrown. near line ... [select table.Id from Entities.Table table where CONTAINS(table.*,:p0) order by table.Id asc]
at NHibernate.Hql.Ast.ANTLR.ErrorCounter.ThrowQueryException()
at NHibernate.Hql.Ast.ANTLR.HqlParseEngine.Parse()
at NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.Parse(Boolean isFilter)
at NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.DoCompile(IDictionary`2 replacements, Boolean shallow, String collectionRole)
at NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.Compile(IDictionary`2 replacements, Boolean shallow)
at NHibernate.Engine.Query.HQLQueryPlan..ctor(String hql, String collectionRole, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)
at NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(String queryString, Boolean shallow, IDictionary`2 enabledFilters)
at NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(String query, Boolean shallow)
at NHibernate.Impl.AbstractSessionImpl.CreateQuery(String queryString)
So it would seem the HQL parser chokes on the asterisk. I thought of doing this:
CONTAINS(table.Column1, :value) or CONTAINS(table.Column2, :value)
Not only is this inefficient, it can also yields incorrect results depending on the full text predicate in :value.
I tried customizing my dialect as per these instructions, but that doesn't help because you're still left with the same problem: specifying table.* causes the HQL parser to fall over.
I thought of specifying query substitutions:
<property name="query.substitutions">TABLECONTAINS(=CONTAINS(table.*,</property>
And then simply doing:
TABLECONTAINS(:value)
But that does not work. I'm not sure why - judging by the resultant error, the substitution just doesn't take place because "TABLECONTAINS" is still present in the query. Besides, this wouldn't work for all cases because I'd need to know the alias of the table and dynamically substitute it in.
Therefore, I rolled an interception-based approach:
using System;
using NHibernate;
using NHibernate.SqlCommand;
public class ContainsInterceptor : EmptyInterceptor
{
public override SqlString OnPrepareStatement(SqlString sql)
{
var indexOfTableContains = sql.IndexOfCaseInsensitive("TABLECONTAINS(");
if (indexOfTableContains != -1)
{
var sqlPart = sql.ToString();
var aliasIndex = sqlPart.LastIndexOf("Table ", indexOfTableContains, StringComparison.Ordinal);
if (aliasIndex == -1)
{
return sql;
}
aliasIndex += "Table ".Length;
var alias = sqlPart.Substring(aliasIndex, sqlPart.IndexOf(" ", aliasIndex, StringComparison.Ordinal) - aliasIndex);
sql = sql.Replace("TABLECONTAINS(", "CONTAINS(" + alias + ".*,");
}
return base.OnPrepareStatement(sql);
}
}
This works and I will now be able to sleep tonight, but I do feel a sudden desire to attend London's impending papal procession and shout out a confession.
Can anyone suggest a better way to achieve this?
Why not use an ISQLQuery instead?
You can still retrieve entities, see http://nhibernate.info/doc/nh/en/index.html#querysql-creating
I would think that a custom dialect would be the appropriate way to handle this. You can find some guidance in this article. I've used this approach to register SQL Server-specific functions like ISNULL for use in our projects.
I use the code below as an HTMLHelper which gets data from the database and loops over it to display a menu. This is fairly straightforward as you can see however, what if you have a database table using the adjacent model of hierarchies eg/ID, ParentID, OrderID. Easy to see whats going on but recursion is needed to get this data out properly. Is writing a C# recursive function acceptable? If so can someone help me with that? The expected output is something similar to this..
<ul>
<li>Item1
<ul>
<li>SubItem1</li>
</ul>
</li>
</ul>
SQL 2008 has a Hierarchy datatype now so I am not sure if this will help things?
I would also like some way of enabling users to decide what goes in a menu for example, a list of items that can go in the menu and then choosing these items and their positions in the hierarchy. Once a saved button is pressed it will store this heirarchy in the database.
Am I asking too much, I'm sure this must be quite a common scenario?
Here is my HTMLHelper code if anyone wants to use it...
public static string Menu(this HtmlHelper helper, int MenuCat)
{
string menuHTML = "<ul id=\"menu\">";
var route = helper.ViewContext.RequestContext.RouteData;
string currentPageName = route.GetRequiredString("id");
DB db = DB.CreateDB();
//var result = from p in db.WebPages where p.CategoryID == 9 select p;
var result = from p in db.WebPages select p;
foreach (var item in result)
{
if (item.Name == currentPageName)
{
menuHTML += "\n\t<li>" + helper.ActionLink(item.Name, "Details", "Dinner", new { id = item.ID }, new { #class = "selected" }) + "</li>";
}
else
{
menuHTML += "\n\t<li>" + helper.ActionLink(item.Name, "Details", "Dinner", new { id = item.ID }, null) + "</li>";
}
}
menuHTML += "\n</ul>\n";
return menuHTML;
}
I would do two things here: don't bother rendering this yourself: use jQuery. If you Google "jquery menu" you'll find hundreds of links.
Next, put the ordering logic on your app, you don't need the DB to do this as it soaks up cycles and (from what I've read) isn't terribly efficient. This is simple looping logic with a self-referencing join that Linq is perfect for.
Hand this off to jQuery, adn you're good to go without hard-coding HTML in code :)
If you are using Sql server 2005 take a look to Common Table Expression (CTE) (google with CTE hierarchical data). It allows you to create a view displaying the complete hierarchy.
But, how much depth level are you displaying in the menu? Usually you only need to show directy childs and go down in the hierarchy as the user clicks the links. (No recursion needed)
I always use recursive table-valued functions for fetching hierarchical data in SQL server.
See an example here:
blogs.conchango.com/christianwade/archive/2004/11/09/234.aspx
Unfortunately, there is a recursion limit (32 levels maximum) for SQL Server User Defined Functions (UDF) and Stored Procedures.
Note: If you use a table-valued function just drop it in your dbml file and you will be able to access it like any other table.
Another approach is to use the a new recursive queries syntax (in the form of the WITH clause and Common Table Expressions-CTE) introduced in SQL Server 2005.
Take a look here:
www.eggheadcafe.com/articles/sql_server_recursion_with_clause.asp
An approach of mixing CTE with Linq-To-SQL is presented here:
stackoverflow.com/questions/584841/common-table-expression-cte-in-linq-to-sql