ICollection does not contain a definition for 'Contains' - c#

I am trying to check whether a SearchResultEntry contains a certain attribute. For this, I am trying the following code:
if(searchResultEntry.Attributes.AttributeNames.Contains(propertyName))
but this fails with the error
ICollection does not contain a definition for Contains, and the best extension method overload "Queryable.Contains<string>(IQueryable<string>, string)" requires a receiver of type "IQueryable<string>".
I also tried to make it an IQueryable using AttributeNames.AsQueryable(), but on that IQueryable, Contains is not available as well.
What is wrong here? When IntelliSense tells me something is available, but then, when I got to that very type, it is still unavailable, am I missing some references or using directives?

Related

DbSet not seeing LINQ definitions

To clear up the obvious first, I am:
using System.Linq;
using System.Collections.Generic;
Have a project reference to System.Core
My DbSet and DbContext classes are defined properly
The strange thing is, intellisense sees it, but I have a compiler warning and it won't compile.
I have tried cleaning the project first, restarting Visual Studio, etc and it still is complaining about:
Error CS1929 'DbSet' does not contain a definition for 'ToList' and the best extension method overload 'Enumerable.ToList(IEnumerable)' requires a receiver of type 'IEnumerable'
My "receiver" in this case is the compiler statically-determined var.
This is a new laptop and a fresh Visual Studio install ... is there something obvious I am missing here?
I wanted these internal but tried switching everything pubilc just to be sure, but I am getting the same error.
Most people report this when they are missing the using clause for Linq but I have that, and intellisense sees it which is where I am getting confused.
Line in question:
var excludedUrls = db.ExcludedUrls.ToList<string>();
I assume that in your code db is a Dbcontext with a property ExcludedUrls of type DbSet<TEntity>
DbSet<TEntity> implements IEnumerable<TEntity> If you have included LINQ, you can use the extension method Enumerable.ToList<TEntity>().
Because of your error I assume that TEntity is not a string. Your code will compile if you leave out the part:
var excludedUrls = db.ExcludedUrls.ToList();
However, this might not give a list with the elements you want. Somehow you'll have to convert each excludedUrl in your source sequence to the string representation that you want. If ToString() does not do this, you'll have to create a function yourself:
class MyDbContext : DbContext
{
public DbSet<MyTSource> ExcludedUrls {get; set;}
}
void string Transform(MyTSource excludedUrl)
{
...
}
List<string> result = dbContext.ExcludedUrls
.Select(excludedUrl => Transform(excludedUrl)
.ToList();
In words: from the sequence of excludedUrls, take each element, and transform it to a string using Transform. Convert the resulting sequence of strings to a list, which will be a list of strings
By the way, did you notice I used ToList without mentioning <string>? The compiler is able to detect the type of the elements in your input sequence, and can create a List of the same type of elements.
Consider avoiding mentioning the TSource when using the Linq functions. This has several advantages:
less typing
Easier to change the source sequence, or intermediate linq statements
Easier to detect the resulting type (and thus easier to detect the error you mentioned)
It allows the use of anonymous types
The answer, it turns out, is not calling the generic form of ToList<> here, but instead calling straight ToList(), which returns a generic List<ExcludedUrl>. A thank you to Ivan Stoev in the comments section for the tip.
I was relying too much on Intellisense hints here and not enough on memory.
As you can see, due to the way extension methods work, it presented me with a ToList in its generic form, which is why my code was written the way it was.

InsertAllOnSubmit<TSubEntity> when to use?

In LINQ to SQL, my understanding is that when I want to insert a collection of objects I am going to be using InsertAllOnSubmit. What I don't understand is when would I need to use InsertAllOnSubmit<T> as opposed to using just InsertOnSubmit?
What are the differences in either or with respect to the generic type parameter.
From LINQ definition,
public void InsertAllOnSubmit<TSubEntity>(IEnumerable<TSubEntity> entities)
where TSubEntity : TEntity;
using like this:
db.SlickTableEntries.InsertAllOnSubmit<SlickTableEntry>(entries);
db.SubmitChanges();
vs. using it like this:
db.SlickTableEntries.InsertAllOnSubmit(entries);
db.SubmitChanges();
entries is a List<SlickTableEntry>.
How should I properly use this? Which version is better?
It is a convenience method that allows you to insert multiple entities in one call. This saves you the foreach loop. It does not change the way the database is accessed but it might be a little less CPU efficient according to the decompiled code (tiny effect).
The generic type parameter exists so that you can pass a derived type if your entities are in an inheritance relationship. Starting with C# covariance support this is no longer needed.
Which one should be used in what situation?
If you have a list of entities use the list version. Otherwise, use the single item version. Do not specify the generic type argument. It is never required and just clutters the code.
There is no functional difference whatsoever. If it compiles it works. Just leave out the type argument and the compiler fills it in appropriately.

Get Type of Object from String Value

I am writing a customer class which will read CS files and spit out information based on method names and their various parameters.
This essentially reads each line looking for keys (public, class, etc) and then sees what its all about. Anyway this bit works fine, what I'm having issues with is dealing with various different Types.
So what I need to do is work out whether the type is one found natively in .Net, or something I've created, I'm really not bothered which way round just as long as I have some way of telling.
I've tried Type t = Type.GetType("My.Namespace.Classname"); but this just returns null even with the full namespace and name of my custom class object. However if I was to do the same code but with System.String it works perfectly fine, but I can't really account for each possible namespace in the entire framework. This will mean I need a way to get the type without the full namespace, or know how to check my own custom objects using GetType.
Can anybody provide any suggestions on how to go about this? Even if it was creating a new instance of the objects that would be enough, but again I don't have the full namespace for .Net objects.
Edit: Bit of a background
What I'm doing is reading classes that I've created in a StreamReader, reason being that I'm creating lots of them and need to do making between objects that one system will be able to understand, and another, so this code would read everything and just create the mapping for me. And in most cases this is perfectly fine, it is only when I have custom types, so I want to identify these are mark them.
I've tried Type t = Type.GetType("My.Namespace.Classname"); but this
just returns null
You need to provide the full assembly-qualified name:
Type t = Type.GetType("My.Namespace.Classname, MyAssembly");
From MSDN:
Parameters
typeName
Type: System.String
The assembly-qualified name of the type to get. See AssemblyQualifiedName. If the type is in the currently executing
assembly or in Mscorlib.dll, it is sufficient to supply the type name
qualified by its namespace.
Anyway, if you're looking to parse C# code an analyze it, I would take a look at NRefactory - an open source C# parser -.
Here's an introduction in CodeProject to NRefactory.
I've tried Type t = Type.GetType("My.Namespace.Classname"); but this just returns null even with the full namespace and name of my custom class object.
I suspect that's because it's not in the calling assembly or mscorlib, which are the only two assemblies checked by Type.GetType for names which aren't assembly-qualified.
If you know all the assemblies involved, you could run through each of them calling Assembly.GetType(namespaceQualifiedName) on each of them.
However, if you don't even have the namespace-qualified name, you should possibly create a lookup of all types in all the relevant assemblies, based on their names. For example:
var lookup = assemblies.SelectMany(a => a.GetTypes())
.ToLookup(t => t.Name);
At that point, for each name you have(e.g. Classname in your example) you can find all the types with that name:
foreach (var type in lookup[name])
{
// Do something with type
}
Type.GetType(some_type_name) will return type object if some_type_name is name of type declared any assemblies loaded at the moment, or in Mscorlib.dll
So if your are parsing your types from .cs files and not loading assebly - it will always be null with types names from your source file

cant use linq "Last()" method

I dont know a whole lot about C# but I have this project I am working on where I would like to do something like this:
SortedDictionary<int, List<ChessMove>> possibleMovesByRank = new SortedDictionary<int, List<ChessMove>>();
...
var best = possibleMovesByRank.Keys.Last();
From what I have been able to find, this should use linq to return the key that has the highest value, however VS is giving me an error:
SortedDictionary.KeyCollection does not contain a definition for 'Last' and no extension method for 'Last'
Am I missing something or is my project not set up correctly or something?
Most likely, you are missing the System.Linq namespace in your C# file. This is an Extension Method and Enumerable.Last will not exist unless you include the relevant namespace.

How do I cast into a type that I got from a String(=the name of the class) at runtime?

I need to cast like this:
/* Cast Brakets */
(Type.FromString(mystring))myObject.doSomething();
I need to get the type that I cast at runtime, in this particular case I can't use a generic "T" class or method.
Although if you had a way of changing the T-generic Type at runtime (without calling a class or method again) that would also help.
Here is a more specific version of my problem:
I have a List comboList and my GUI can add new ComboBoxes at runtime, these will automatically be put into comboList. Now there are database tables for each of those ComboBoxes in comboList. I added the name of each of the database classes in the .Tag field of each ComboBox
(example: combobox_users.Tag = "users_databaseClass")
Now at runtime I need to cast into the type of users_databaseClass for example, but it appears to me that this is impossible. It appears that this is simply not possible to put a Type into cast-brackets at runtime to actually cast that type.
Help would be greatly appreciated, I've been trying for days.
To use the properties and methods of a wacky type, you'll need a reference to that type (e.g. Type.GetType("string_name_of_type")) and you'll need some pretty cool reflection (e.g. theType.GetMethod("method_name")). Your performance won't be great. See http://msdn.microsoft.com/en-us/library/system.type.getmethod(v=vs.71).aspx

Categories