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

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();

Related

LINQ: Select First Item from Table A that has corresponding ID in linking table that connects to Table B

I currently have an 'Inspirations' table with ID, Name, and Description, a 'Photos' table with ID, Name, and Description, and a linking table InspirationPhotos that just has the foreign keys of PhotoID and InspirationID. I want to select the first photo that is associated with each InspirationID. I know that I will likely need to loop through the Photos table and then select FirstOrDefault.
I think I will need something like
foreach (var inspiration in Inspirations)
{
inspiration.Photos.Where(x=>x.PhotoId == ?)
}
Maybe I should add a primary key to the linking table?
Thanks in advance
You can do it like this:
var inspirationPhotos = db.Inspirations.Select(i => new {
Inspiration = i
, Photo = db.Photos.FirstOrDefault(p =>
db.InspirationPhotos.Any(ip =>
ip.PhotoId == p.Id && ip.InspirationId == i.Id
)
)
}).

Get values of foreign keys tables linked in c#

I have a question about foreign keys in a database. I am programming in c#, using the Entity framework (visual studio winforms) and I have data in my sql database with foreign keys.
I have queries which access these data to get them in a Datagrid. Everything is OK, except I have data in tables which are foreign keys (numbers). When I select them with queries I only get the foreign key (a number) and not the value which is linked in another table.
var requete_reservations = from reservation_spa in bdd.reservation_spa
where reservation_spa.NOMBRE_RESERVATION > 0
select new
{
reservation_spa.CLIENT,
reservation_spa.SPA,
reservation_spa.NOMBRE_RESERVATION
};
dataGrid_reservations.DataSource = requete_reservations.ToList();
In reservation_spa.client I have a number which links another table client
How can I get the Name from client using the foreign keys in reservation_spa?
You must Join table reservation_spa and Client like this :
var requete_reservations = from r in bdd.reservation_spa
join c in bdd.client on r.CLIENT equals c.IDCLIENT
where r.NOMBRE_RESERVATION > 0
select new
{
c.NOM,
r.SPA,
r.NOMBRE_RESERVATION
};
Where is the name for? If you just need the name you could use linq
var name= from c in bdd.Clients //Is that the name of the table of clients?
where c.IDClient= requete_reservations.Client
select c;

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.

linq-to-sql conditional read

I'm writing a query that looks like this:
var TheOutput = (from x in MyDC.MyTable
where.....
select new MyModel()
{
MyPropID = (from a in MyDC.MyOtherTable
where....
select a.ElementID).SingleOrDefault(),
MyPropData = (from a in MyDC.MyOtherTable
where a.ElementID == MyPropID
select a.ElementData).SingleOrDefault(),
}
I'm filling up MyModel with several properties from the database. Two of these properties are filled by reading another table. At the moment, I first read MyPropID to see if there's an element in the other table and then I read the other table again to get the data, regardless of whether or not an ID was retrieved.
How can I eliminate this second read if I know, from reading MyPropID and returning a null, that there's no data that matches the where a.ElementID == MyPropID clause.
Thanks.
var TheOutput = (from x in MyDC.MyTable
where.....
let id = (from a in MyDC.MyOtherTable
where....
select a.ElementID).SingleOrDefault()
select new MyModel()
{
MyPropID = id,
MyPropData = (from a in MyDC.MyOtherTable
where id != null && a.ElementID == id
select a.ElementData).SingleOrDefault()
}
If your code would create a single SQL statement from this query I do not think checking for null would matter. If this query would result in multiple SQL statements it might.

linq to entities inheritance query problem

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)

Categories