I have a list of names in a observable collection returned from wcf service and database is oracle, I want to make full text search on the list using LINQ.
service is consumed in silverlight application.
Any suggestions pls.
How about this?
var found = thelist.Where(str => str.Contains(strToSearchFor));
or maybe this -
var found = thelist.Where(str => str.ToLower().Contains(strToSearchFor.ToLower()));
if it is not list of strings it would like like this:
var found = thelist.Where(obj => obj.strProperty.Contains(strToSearchFor));
If you need this solution to be case insensitive the solution of Hogan can be done without creatring a new string (by using the ToLower() method).
First, create an extension method:
public static class Extensions
{
public static bool Contains(this string source, string stringToMatch, StringComparison comparisonType)
{
return source.IndexOf(stringToMatch, comparisonType) >= 0;
}
}
Then you can make the Hogan solution case insensitive like this:
var found = thelist.Where(str => str.Contains(strToSearchFor, StringComparison.OrdinalIgnoreCase));
Related
How can I make a query on List<string> with Lucene? Here is my attempt, but I got an error.
var top10MoviesQuery = session.Advanced.DocumentQuery<Media, Media_Index>()
.SetResultTransformer("MediaListTransformer")
.SelectFields<MediaListProjection>()
.WhereEquals(o => o.AvalibleOnServices, serviceMovie) <---- here
.OrderByDescending(o => o.OurScore)
.Take(10)
.Lazily();
AvalibleOnServices is a List<string>() and serviceMovie is a string.
I'm assuming your purpose is to query documents which AvailableOnServices list contains serviceMovie. If that's the case you could just do something like this, you don't need Lucene for such a simple thing:
var top10MoviesQuery = session.Query<Media, Media_Index>()
.Where(x => x.AvailableOnServices.Contains(serviceMovie))
.Take(10)
.TransformWith<MediaListTransformer, MediaListProjection>()
.Lazily();
Note that:
Here I assume that MediaListProjection is what MediaListTransformer transforms into, since you didn't mention otherwise, and
you need to add using Raven.Client.Linq; to be able to invoke TransformWith on the results - by importing this namespace you will get an IRavenQueryable<T> instead of a regular IQueryable<T> when you call Where, so you will be able to invoke Raven-specific stuff such as TransformWith and Lazily.
I wanted to take advantage of built-in content negotiator and just get access to decision what formatter is going to be used. I don't want to use Request.Headers.Accept and check for whether it is json or xml content type because there lot of things are involved in that decision. Is there a way I can check at controller level or override any class that tells me what formatter going to be used OR what request content type is?
thanks in advance.
You can run conneg manually:
var conneg = Configuration.Services.GetContentNegotiator();
var connegResult = conneg.Negotiate(
typeof(YOUR_TYPE), Request, Configuration.Formatters
);
And use the output whichever way you want:
//the valid media type
var mediaType = connegResult.MediaType;
//do stuff
//the relevant formatter
var formatter = connegResult.Formatter;
//do stuff
If you want to see what is going on then install a TraceWriter and you will see what the conneg does.
A TraceWriter looks something like:
public class TraceWriter : ITraceWriter {
public bool IsEnabled(string category, TraceLevel level) {
return true;
}
public void Trace(HttpRequestMessage request, string category, TraceLevel level, Action<TraceRecord> traceAction) {
var rec = new TraceRecord(request, category, level);
traceAction(rec);
Log(rec);
}
private void Log(TraceRecord record) {
Console.WriteLine(record.Message);
}
}
and is installed like this,
config.Services.Replace(typeof(ITraceWriter), new TraceWriter());
If you want to manually invoke conneg then you can use,
config.Services.GetContentNegotiator().Negotiate(...)
Tugberk has a blog on this. Have a look.
I want to do case sensitive queries against dynamic fields in a RavenDB index. I have seen that this can be done using an AbstractAnalyzerGenerator thing, but I have not found information on how to use it.
My document class looks similar to:
class Thing {
public string Name;
public DateTime CreatedAt;
public Dictionary<string, object> Properties;
}
The index map is set up like this:
Map = things => from thing in things
select new { Name = thing.Name,
CreatedAt = thing.CreatedAt,
_ = thing.Properties.Select( p =>
p.CreateField(p.Key, p.Value, false, true) );
}
Now I would like to use this magic AbstractAnalzyzerGenerator thing to make some of the property fields case sensitive, based on their name. Unfortunately I don't know how.. :)
ErikR,
If you need case sensitive, you need to do it like this:
p.CreateField(p.Key, p.Value, false, **false**) );
I need to parse an expressiontree to get a sql where clause.
Aren't there any classes in the .NET FX or any third party library which already have this abilities ?
I mean Linq2SQL, EntityFramework , all of them have to do this, so does anyone know, if there is something that can be reused instead of reinventing the wheel?
MyType.Where(Func<TEntity,bool>((entity)=>entity.Id == 5)))
now i need to get the corresponding string representing a where clause:
where abc.Id = "5"
this is just an simple example. it should also work with logical conjunctions.
I know I can create the expressiontree and parse it on my own, but i think there could be something already existing, which I'm missing
You could create an ExpressionVisitor with the sole purpose of finding and processing the where calls. Making this task very easy to handle.
e.g.,
public class WhereCallVisitor : ExpressionVisitor
{
protected override Expression VisitMethodCall(MethodCallExpression node)
{
var method = node.Method;
if (method.Name == "Where" && method.DeclaringType == typeof(Queryable))
{ // we are in a Queryable.Where() call
ProcessWhereCall(node);
}
return base.VisitMethodCall(node);
}
private void ProcessWhereCall(MethodCallExpression whereCall)
{
// extract the predicate expression
var predicateExpr = ((dynamic)whereCall.Arguments[1]).Operand as LambdaExpression;
// do stuff with predicateExpr
}
// p.s., dynamic used here to simplify the extraction
}
Then to use it:
var query = from row in table
where row.Foo == "Bar"
select row.Baz;
var visitor = new WhereCallVisitor();
visitor.Visit(query.Expression);
I am having a minor problem with WCF service proxies where the message contains List<string> as a parameter.
I am using the 'Add Service reference' in Visual Studio to generate a reference to my service.
// portion of my web service message
public List<SubscribeInfo> Subscribe { get; set; }
public List<string> Unsubscribe { get; set; }
These are the generated properties on my MsgIn for one of my web methods.
You can see it used ArrayOfString when I am using List<string>, and the other takes List<SubscribeInfo> - which matches my original C# object above.
[System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false)]
public System.Collections.Generic.List<DataAccess.MailingListWSReference.SubscribeInfo> Subscribe {
get {
return this.SubscribeField;
}
set {
if ((object.ReferenceEquals(this.SubscribeField, value) != true)) {
this.SubscribeField = value;
this.RaisePropertyChanged("Subscribe");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false)]
publicDataAccess.MailingListWSReference.ArrayOfString Unsubscribe {
get {
return this.UnsubscribeField;
}
set {
if ((object.ReferenceEquals(this.UnsubscribeField, value) != true)) {
this.UnsubscribeField = value;
this.RaisePropertyChanged("Unsubscribe");
}
}
}
The ArrayOfString class generated looks like this. This is a class generated in my code - its not a .NET class. It actually generated me a class that inherits from List, but didn't have the 'decency' to create me any constructors.
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
[System.Runtime.Serialization.CollectionDataContractAttribute(Name="ArrayOfString", Namespace="http://www.example.com/", ItemName="string")]
[System.SerializableAttribute()]
public class ArrayOfString : System.Collections.Generic.List<string> {
}
The problem is that I often create my message like this :
client.UpdateMailingList(new UpdateMailingListMsgIn()
{
Email = model.Email,
Name = model.Name,
Source = Request.Url.ToString(),
Subscribe = subscribeTo.ToList(),
Unsubscribe = unsubscribeFrom.ToList()
});
I really like the clean look this gives me.
Now for the actual problem :
I cant assign a List<string> to the Unsubscribe property which is an ArrayOfString - even though it inherits from List. In fact I cant seem to find ANY way to assign it without extra statements.
I've tried the following :
new ArrayOfString(unsubscribeFrom.ToList()) - this constructor doesn't exist :-(
changing the type of the array used by the code generator - doesn't work - it always gives me ArrayOfString (!?)
try to cast List<string> to ArrayOfString - fails with 'unable to cast', even though it compiles just fine
create new ArrayOfString() and then AddRange(unsubscribeFrom.ToList()) - works, but I cant do it all in one statement
create a conversion function ToArrayOfString(List<string>), which works but isn't as clean as I want.
Its only doing this for string, which is annoying.
Am i missing something? Is there a way to tell it not to generate ArrayOfString - or some other trick to assign it ?
Any .NET object that implements a method named "Add" can be initialized just like arrays or dictionaries.
As ArrayOfString does implement an "Add" method, you can initialize it like this:
var a = new ArrayOfString { "string one", "string two" };
But, if you really want to initialize it based on another collection, you can write a extension method for that:
public static class U
{
public static T To<T>(this IEnumerable<string> strings)
where T : IList<string>, new()
{
var newList = new T();
foreach (var s in strings)
newList.Add(s);
return newList;
}
}
Usage:
client.UpdateMailingList(new UpdateMailingListMsgIn()
{
Email = model.Email,
Name = model.Name,
Source = Request.Url.ToString(),
Subscribe = subscribeTo.ToList(),
Unsubscribe = unsubscribeFrom.To<ArrayOfString>()
});
I prefer not to return generic types across a service boundary in the first place. Instead return Unsubscribe as a string[], and SubscriptionInfo as SubscriptionInfo[]. If necessary, an array can easily be converted to a generic list on the client, as follows:
Unsubscribe = new List<string>(unsubscribeFrom);
Subscribe = new List<SubscriptionInfo>(subscribeTo);
Too late but can help people in the future...
Use the svcutil and explicitly inform the command line util that you want the proxy class to be serialized by the XmlSerializer and not the DataContractSerializer (default). Here's the sample:
svcutil /out:c:\Path\Proxy.cs /config:c:\Path\Proxy.config /async /serializer:XmlSerializer /namespace:*,YourNamespace http://www.domain.com/service/serviceURL.asmx
Note that the web service is an ASP.NET web service ok?!
If you are using VS 2008 to consume service then there is an easy solution.
Click on the "Advanced..." button on the proxy dialog that is displayed when you add a Service Reference. In the Collection Type drop down you can select System.Generic.List. The methods returning List should now work properly.
(Hope this is what you were asking for, I'm a little tired and the question was a tad difficult for me to read.)