Dyamic Linq -- strings to table and property names - linq

I've looked at the older Dynamic Linq library. It doesn't suit my needs as far as I can tell as it primarily looks at returning query data (to which there are several examples of doing this dynamically).
I have a db table that contains the type, table, and column(property). I would like to do dynamic inserts, such as:
var x = new _context.[table name as string from db];
x.[property name as string from db] = 4;
_context.Add(x);
_context.SaveChanges();
Not sure if this is possible (or if so, how to go about with the implementation).

Related

How to obtain column metadata from linq to Entities query?

I need to support legacy client and compose ADO datasets from our Linq queries. The problem is how get specific column information (varchar length, decimal precision, etc) that cannot be obtained using reflection.
for example, I have table Customer with field Name varchar(80)
When I fetch data from linq to entities query:
var data = (from c in ctx.Customers select c.Name).ToList()
I cannot obtain maxSize for the column data[i].Name and adodataset raises an error.
I already have simple solution:
Code to extract column metadata from ObjectContext by property reference
Simple code that parses expression from Queryable and links output properties to edm columns.
But I have a lot of issues parsing complex queries that include multiple nested groupbys/unions/joins etc.
Does anybody know any other way (maybe using materialization shaper or similar)?
Thanks to EFProviderWrappers by Joseph Kowalski I have made similar provider and published it on codeplex

What's a LINQ query to search through related (1:m) records for a specific string?

I thought I'd find an answer readily, but not so far. I have related tables -- Blog and Tags. The Tags schema looks like this:
TagTableID (identity column)
BlogID (foreign key)
Tag (string)
The tables are related in SQL Server. Each blog entry can have multiple tags, and each tag for a blog entry generates a new entry in the Tags table. I want to search for blog entries that have specific tags in them. I can do this in Linq:
var blogQuery =
from blogentry in blog.blogs
where blogentry.Tags = [??]
select blogentry;
Since there's multiple tags per blog entry, blogentry.Tags is available in Linq and returns an EntitySet. But I don't know how to search (I guess) the resulting collection to find a specific string. (The bit where it says [??] in the example above.)
I suspect this requires a more complex query, but this is where I've started ...
I assume you're using Linq 2 SQL or Linq 2 Entities?
I didn't test this, but I believe something like this should work:
var tagsToLookFor = new[] {"tag1", "tag2"};
var blogQuery =
from blogentry in blog.blogs
where blogentry.Tags.Any(t => tagsToLookFor.Contains(t.Tag))
select blogentry;
Do verify the resulting SQL with SQL profiler though.

Set column type dynamically in LINQ

I want to set the column names of an output from LINQ dynamically. Like so:
summary Rows.Field<Type>("Name")
I need to do this because I have to do the order by on three columns based on the a condition and each column have 2 different types like float, int and double
Does anyone have any suggestions on how this can be done?
LINQ to SQL deals with static types, though there are some tricks you can do. You can't change the type of the field on the fly, other than to use Convert.ToInt32, etc. to change the appropriate type to the value you need at the time you want to cast it.
Alternatively, you could try casting the value to each of the three types from the query:
from c in ctx
select new
{
IntVal = c.Value,
DoubleVal = Convert.ToDouble(c.Value),
.
.
}
This way, you'd have all three cast appropriately and can suck in the correct field. When working with the record, you can even use a wrapper around reflection to get something similarly to what you want. I don't know of Convert is LINQ supported, but you should be able to do something similarly.
HTH.

LINQ - NOT selecting certain fields?

I have a LINQ query mapped with the Entity Framework that looks something like this:
image = this.Context.ImageSet
.Where(n => n.ImageId == imageId)
.Where(n => n.Albums.IsPublic == true)
.Single();
This returns a single image object and works as intended.
However, this query returns all the properties of my Image table in the DB.
Under normal circumstances, this would be fine but these images contain a lot of binary data that takes a very long time to return.
Basically, in it current state my linq query is doing:
Select ImageId, Name, Data
From Images
...
But I need a query that does this instread:
Select ImageId, Name
From Images
...
Notice i want to load everything except the Data. (I can get this data on a second async pass)
Unfortunately, if using LINQ to SQL, there is no optimal solution.
You have 3 options:
You return the Entity, with Context tracking and all, in this case Image, with all fields
You choose your fields and return an anonymous type
You choose your fields and return a strongly typed custom class, but you lose tracking, if thats what you want.
I love LINQ to SQL, but thats the way it is.
My only solution for you would be to restructure your DataBase, and move all the large Data into a separate table, and link to it from the Image table.
This way when returning Image you'd only return a key in the new DataID field, and then you could access that heavier Data when and if you needed it.
cheers
This will create a new image with only those fields set. When you go back to get the Data for the images you select, I'd suggest going ahead and getting the full dataset instead of trying to merge it with the existing id/name data. The id/name fields are presumably small relative to the data and the code will be much simpler than trying to do the merge. Also, it may not be necessary to actually construct an Image object, using an anonymous type might suit your purposes just as well.
image = this.Context.ImageSet
.Where(n => n.ImageId == imageId)
.Where(n => n.Albums.IsPublic == true)
.Select( n => new Image { ImageId = n.ImageId, Name = n.Name }
.Single();
[If using Linq 2 SQL] Within the DBML designer, there is an option to make individual table columns delay-loaded. Set this to true for your large binary field. Then, that data is not loaded until it is actually used.
[Question for you all: Does anyone know if the entity frameworks support delayed loaded varbinary/varchar's in MSVS 2010? ]
Solution #2 (for entity framework or linq 2 sql):
Create a view of the table that includes only the primary key and the varchar(max)/varbinary(max). Map that into EF.
Within your Entity Framework designer, delete the varbinary(max)/varchar(max) property from the table definition (leaving it defined only in the view). This should exclude the field from read/write operations to that table, though you might verify that with the logger.
Generally you'll access the data through the table that excludes the data blob. When you need the blob, you load a row from the view. I'm not sure if you'll be able to write to the view, I'm not sure how you would do writes. You may be able to write to the view, or you may need to write a stored procedure, or you can bust out a DBML file for the one table.
You cannot do it with LINQ at least for now...
The best approach I know is create View for the table you need without large fields and use LINQ with that View.
Alternatively you could use the select new in the query expression...
var image =
(
from i in db.ImageSet
where i.ImageId == imageId && i.Albums.IsPublic
select new
{
ImageId = i.ImageId,
Name = i.Name
}
).Single()
The LINQ query expressions actually get converted to the Lambda expression at compile time, but I prefair using the query expression generally because i find it more readable and understandable.
Thanks :)

Linq stored procedure with dynamic results

So I'm extremely new to Linq in .Net 3.5 and have a question. I use to use a custom class that would handle the following results from a store procedure:
Set 1: ID Name Age
Set 2: ID Address City
Set 3: ID Product Price
With my custom class, I would have received back from the database a single DataSet with 3 DataTables inside of it with columns based on what was returned from the DB.
My question is how to I achive this with LINQ? I'm going to need to hit the database 1 time and return multiple sets with different types of data in it.
Also, how would I use LINQ to return a dynamic amount of sets depending on the parameters (could get 1 set back, could get N amount back)?
I've looked at this article, but didn't find anything explaining multiple sets (just a single set that could be dynamic or a single scalar value and a single set).
Any articles/comments will help.
Thanks
I believe this is what you're looking for
Linq to SQL Stored Procedures with Multiple Results - IMultipleResults
I'm not very familiar with LINQ myself but here is MSDN's site on LINQ Samples that might be able to help you out.
EDIT: I apologize, I somehow missed the title where you mentioned you wanted help using LINQ with Stored Procedures, my below answer does not address that at all and unfortunately I haven't had the need to use sprocs with LINQ so I'm unsure if my below answer will help.
LINQ to SQL is able hydrate multiple sets of data into a object graph while hitting the database once. However, I don't think LINQ is going to achieve what you ultimately want -- which as far as I can tell is a completely dynamic set of data that is defined outside of the query itself. Perhaps I am misunderstanding the question, maybe it would help if you provide some sample code that your existing application is using?
Here is a quick example of how I could hydrate a anonymous type with a single database call, maybe it will help:
var query = from p in db.Products
select new
{
Product = p,
NumberOfOrders = p.Orders.Count(),
LastOrderDate = p.Orders.OrderByDescending().Take(1).Select(o => o.OrderDate),
Orders = p.Orders
};

Resources