I decided that constantly writing a long winded code to select data from a table was a bad method to use when I am constantly having to reference between tables, therefore I decided to write a class that handles the queries for me and returns the rows.
public Database(object query, object name)
{
var tbl = (from c in db.name where query select c).ToArray();
return tbl;
}
I am sort of new to Entity and am having a hard time trying to understand the type name should be.
At first I tried object which gave me this error:
'Model.Container' does not contain a definition for 'name' and no extension method 'name' accepting a first argument of type 'Model.rkdb_07022016Entities2' could be found (are you missing a using directive or an assembly reference?)
So I knew that the table name I am selecting from cannot be passed through as type object.
I took an educated guess and tried to make name type Queryable but still no luck.
Could anyone possibly point me in the right direction and add some references where I can maybe learn how to tackle these situations in the future?
Thank-you.
(putting as an answer for future viewers)
You probably want an Expression<Func<EntityType, bool>>
If you need to make it generic, you could build something with T.
As I said in the comment, it's worth taking a look at Joseph Albahari's PredicateBuilder for sample code (or indeed use it as it is powerful)
Related
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.
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.
I'm new to C# and i'm learning LINQ now and trying to select some data . . .
var carMake = (from table in entity.Make select new { table.ID, table.Name }).ToList();
I wrote the above query but i have an error:
The type of the expression in the select clause is incorrect. Type inference failed in the call to 'Select'.
I searched the web, but couldn't find any solution. I don't know what's wrong with that query.
Thanks in Advance.
This code should be fine as long as entity.Make is a property of type IEnumerable<Table> for some type Table with properties ID and Name. Please make sure that Make has a compatible type for Linq to work with.
It seems possible that some of Make, ID, or Name are methods instead of properties, and you must invoke them (using Make(), ID(), or Name()) where appropriate. Of course, if ID or Name are the culprits, then your syntax for instantiating the anonymous type will become invalid, since you cannot declare new { table.Name() }. Instead, you'll have to do new { Name = table.Name() }. Read more about anonymous type instantiating here.
In your example it is unlikely, but I have had the issue before where one of the anonymously typed objects you are trying to create in your select cause are of a type that you do not have referenced. For example if Name were an XElement, and you did not have a reference to System.Xml.Linq, you would receive this error.
Is there a way to use Meta Tales or Table names to Construct a dynamic query in LINQ?
foreach (var metaTable in db.Mapping.GetTables())
{
var queryType = metaTable.RowType.Type;
var test = from q in db.GetTable(queryType)
select q;
}
Is there a way to do something like this? The attempt above yields the error:
Could not find an implementation of the query pattern for source type 'System.Data.Linq.ITable'. 'Select' not found. Consider explicitly specifying the type of the range variable 'q'.
Thanks,
Chris
The "long answer" is a lot of nasty expression code: You have to build up the expression tree for your query from scratch because the compiler only does it if everything is strongly typed. However if you just want to get all rows, just write
var test = db.GetTable(queryType).Cast<object>();
because the ITable interface is already IEnumerable. Now you still need to make sense of a sequence of untyped objects.
Can you tell us what you want to do and why?
Have you included a reference to the System.Data.Linq namespace? If that is missing you then you'd probably get this error as I think the LINQ extension methods come from that.
This may seem like a simple question however i've spent the last hour trying to solve this.
I want to create a custom subsonic collection so that i can fill it with data from a query with multiple joins using the .ExecuteAsCollection<>(); method.
i've created the custom class and a custom collection and even a controller with the load method but i keep getting a null refernce exception from the ExecuteAsCollection<>();
the stack track says its an error coming from the SubSonic.Load method.
i have left out the class's "SQLProps" that all the other subsonic classes have, but i was hoping i wouldn't have to go through each field painstakingly.
There has to be something simple i'm missing. Can someone who's done this give me a quick run down on what is required by subsonic to fill a custom collection with a query?
thanks
Doug
UPDATE:
i forgot to mention that i also added the public Columns struct with all my columns.
ExecuteAsCollection<T>() will only work with SubSonic-generated collections. You can map the result of a query to an arbitrary object type with ExecuteTypedList<T>(). This will match the columns returned from your query to properties of type T with the same name and give you List<T>.