linq to entities inheritance query problem - c#

I'm trying to perform a linq to entities query on a table that's inherited using Table per Type.
The problem I'm having is that I can't get at the properties on the Inhertied table only the properties on the Base Table.
var qry = from i in _DB.BaseTable
where i is catalogueModel.InheritedTable
// Field Doesn't Exist
// && i.InheritedTableField == "Value"
select i;
When I try to cast the Inherited Table to it's type...
var qry = from i in _DB.BaseTable
where i is catalogueModel.InheritedTable
&& (i as catalogueModel.InheritedTable).InheritedTableField == "Value"
select i;
...the code compiles but i get a cool error which reads
Only text pointers are allowed in work
tables, never text, ntext, or image
columns. The query processor produced
a query plan that required a text,
ntext, or image column in a work
table.
I suppose my question is How are you supposed to access the properties of the Inherited tables in linq to entities when using Table per Type?

Use .OfType():
var qry = from i in _DB.BaseTable.OfType<InheritedTable>()
select i.InheritedTableField;

You can also use IS
var qry = from i in _DB.BaseTable where i is InheritedTable select i.InheritedTableField;
Here are a few others to help (using Entity SQL)
var q = SELECT VALUE c FROM OFTYPE(yourcontext.yourbaseclass, yourmodel.yoursubclass) AS c
var q = SELECT VALUE c FROM yourcontext.yourbaseclass AS c where c IS NOT OF (yourmodel.yoursubclass)

Related

Linq how to use a subSelect as a virtual table in FROM

There may be similar questions out here but none that I could find for doing a subSelect in the FROM clause as a virtual table.
Most of the columns I need are in one table. There are a few columns needed from different tables that I cannot join on without getting a Cartesian join.
Here is my SQL query:
SELECT meter_name, a.loc_id, a.loc_name, a.facility_name, meter_type
FROM meter_table, (SELECT loc_id, loc_name, facility_name
FROM facility_table
WHERE id = 101) a
WHERE meter_id = a.fac_id
I have no idea how to convert this into Linq and it must be done tonight for a demo in the morning.
Assume this represents your meter_table within your database
in this case each element of the list represents a record in the database table holding the appropriate attributes
i.e the table columns will become the properties of each object
List<Meter> meter_table = new List<Meter>();
Assume this represents the facility_table table you want to join with.
same goes here, each element of the list represents a record in the database table holding the appropriate attributes
i.e the table columns will become the properties of each object
List<Facility> facility_table = new List<Facility>();
then perform the inner join like so:
var query = from m in meter_table
join a in facility_table on m.meter_id equals a.fac_id
where a.id == 101
select new { meter_name = m.MeterName,
loc_id = a.LocId,
facility_name = a.FacilityName,
meter_type = m.MeterType
};
where m.MeterName, a.LocId, a.FacilityName, m.MeterType are properties of their respective types.
it's also worth noting the variable query references an IEnumerable of anonymous types. However, if you want to return an IEnumerable of strongly typed objects then feel free to define your own type with the appropriate properties then just change select new to:
select new typeName { /* assign values appropriately */}
of the above query.

Convert sql query to lambda expression for table with foreign keys

I have 2 tables. One is a user table that holds userid and userSelection(foreign key to another table) both are primary keys so multiple rows for a user.
The 2nd table holds columns with it's primary id being userSelection.
I want to retrieve all the userSelection rows that a userId has from the 2nd table. I want to use linq lambda expressions too.
I have it working in sql jsut can't convert it for use in c#.
Select * From column
where colID in (
select colId from users
where userID = 'someUser')
Thanks
Assuming you're using Entity Framework, what you're really looking for is an inner join. it would look something like this:
from c in context.Column
join u in context.Users on c.ColId equals u.ColId
where u.UserId = 'SomeUser'
select c;
as a lambda that is something like (syntax might be lacking something) (no where clause here, but easily added)
context.Column.Join( context.Users, u => u.ColId, c => c.ColId).Select
Change this code to two parts
Select * From column
where colID in (
select colId from users
where userID = 'someUser')
First part to get colId list:
var colIds = context.users.Where(x=>x.userID == "someUser").Select(x=>x.colId).ToList();
Second part to get the result use Where and List.Contains
// IQueryable result
var result = context.column.Where(x=>colIds.Contains(x.colID));
You can use it inline, but I recommend it to be two parts.

Can the EXCEPT operator exclude data where a column contains data from an array

Assume there is a string of text values comma-separated, like an array:
var excludelist ="apples,oranges,grapes,pears";
The excludelist values may come from a query to a table in a database.
Assume a query wherein we want to return all rows EXCEPT those rows where the field named Fruit contains any items from the excludelist.
var qry = from s in context.Groceries.Where(s => s.Fruit(here is where we need to exclude the items??) join u in context.Users on s.Owner equals u.User_ID
Can someone provide a sample Link to SQL answer?
Did you try Except?
var qry = from s in context.Groceries.Except(excludelist)...
Link to SQL has CONTAINS (and!CONTAINS)
where !excludelist.Contains(i)
select i;
I solved it this way:
I have a database table with the names of the fruits I wish to exclude and I created a List (IList apparently won't work).
List<string> excludedfruit = context.ExcludedFruit.Select(x => x.ExcludedFruitName).ToList();
Then I used the following Linq to SQL query (partially shown)
var qry = from s in context.Groceries
.Where(s => !excludedfruit.Contains(s.Fruit))

Linq2SQL: Select only some columns, but still able to submit changes

I need to update a column in a table which contains a lot of rows. Each row has a some large TEXT columns in it, which i do not need for my update.
I'm using LinqPAD, and this is roughly, what i wanna do:
(from s in Table
where s.FK_ID == null
select new{s.FK_ID, s.Datum, s.PBNummer}).ToList()
.ForEach(s => s.FK_ID = new Guid(...some new guid here...));
SubmitChanges();
This does not compile, as the properties of an anonymous class type are read-only.
If I do
(from s in Table
where s.FK_ID == null
select s).ToList()
then I can update and save, but all columns are loaded, which takes a very long time and causes memory problems.
Is there a way to only load some columns but still have an object that i can update and save using SubmitChanges? Or do i have to switch to SQL statements?
Way to update specific columns of a database record in Linq to SQL is to create a View on the table containing large columns, and only include the “short” columns:
CREATE VIEW [dbo].[V_FooMax] AS
SELECT OID, ID
FROM dbo.FooMax
Since views based on single tables are updatable, an update on the view is performed as an update on the table:
using (var database = new DataContext())
{
var fooView = database.V_FooMaxes
.Where(foo => foo.OID == OID).FirstOrDefault();
fooView.ID = newID;
database.SubmitChanges();
}
Reference: http://devio.wordpress.com/2011/01/15/updating-a-single-column-in-linq-to-sql-using-a-view/
Also you can look at: http://devio.wordpress.com/2011/01/16/updating-a-single-column-in-linq-to-sql-summary/
Firstly, if you don't have a primary key in the database, then you wouldn't be able to update via Linq-To-Sql. If you have a primary key, but just don't know which it is, you can find it in Linqpad by doing something like
var table = (from t in Mapping.GetTables()
where t.TableName == "[Table]" select t).SingleOrDefault();
(from dm in table.RowType.DataMembers
where dm.DbType != null && dm.IsPrimaryKey
select dm.Name)
.Dump("Primary Key");
Once you know the primary key, you can do something like the following, (I'm assuming the primary key is called Id)
var oldList = (from s in Table
where s.FK_ID == null
select new{s.Id , s.FK_ID, s.Datum, s.PBNummer}).ToList() ;
This is similar to your query, except I have added the primary key
foreach(var r in oldList)
{
Table t = new Table();
t.Id = r.Id ;
Table.Attach(t);
t.FK_ID = new Guid(...some new guid here...));
}
SubmitChanges();

LINQ: Get Table details

I'm using LINQPad and I would like to know schema details of a table.
I know that I do it using SQL:
SELECT column_name,*
FROM information_schema.columns
WHERE table_name = '{table_name}'
ORDER BY ordinal_position
How can I do this using LINQ?
LINQ to SQL contexts have a Mapping property that you can use for this sort of thing. A query like the one you provided might look something like this:
from t in context.Mapping.GetTables()
where t.TableName == "[table_name]"
from c in t.RowType.DataMembers
orderby c.Ordinal
select new {columnName = c.Name, columnInfo = c}
See this answer for more details.
MetaTable t = MyDataContext.Mapping.GetTables().Where(
i => i.TableName == "TABLENAME").SingleOrDefault();
PropertyInfo[] fields = t.RowType.InheritanceRoot.GetType().GetProperties();
'fields' will contain the names and types of the columns.
In LINQ to SQL, you could try to bring in these views into the model. If that does not work, you could create a stored procedure that retrieves the info, then LINQ to SQL maps the stored procedure and you execute it as a function.

Categories