C# Linq DeleteObject - c#

My problem is that i have 2 tables one about movie datas and the other about rentals and the primary key is the movietitle from the first table and the movietitle foreign key is in the rentals table.
I would like to delete the full row from rentals when on my form user select a movie from the listbox (data from movie table) and the full row from the rentals table becomes deleted (i am trying to delete the primary key of rentals but i get error on the second line :
Error 13 The best overloaded method match for 'System.Data.Objects.ObjectSet.DeleteObject(movies.Rentals)' has some invalid arguments)
var search = (from g in db.Rentals
where g.Movietitle == (string)listbox1.SelectedValue
select g.Szigszam // this is the primary key in the rentals table,the foreign key is the movie title)
.First();
db.Rentals.DeleteObject(search);
db.SaveChanges();

You must do like this.
var search = (from g in db.Rentals
where g.Movietitle == (string)listbox1.SelectedValue
select g).First();
db.Rentals.DeleteObject(search);
db.SaveChanges();

Related

SQLite: The right way to design a database and to access its data with an AUTOINCREMENT ID?

Let's suppose that I have a database containing Artists and their Albums.
CREATE TABLE Artist (
ArtistID INTEGER PRIMARY KEY,
ArtistName TEXT NOT NULL
);
CREATE TABLE Album(
AlbumName TEXT PRIMARY KEY,
ArtistID INTEGER REFERENCES Artist(ArtistID),
Year INTEGER
);
So then I create an application inside of Visual Studio and connect the SQLite database to my project using sqlite/sql server compact toolbox, I then want to manage the database using C#
I create an application for my users. A user wants to find all the albums by a name of an artist.
If my primary key is an autoincrement property, do I have to use syntax like :
public static IQueryable<Artist> GetPossibleArtists(string name)
{
var matches = from match in dB.Artists where match.ArtistName == name select match;
return matches;
}
public static Artist GetFirstArtistIfExists(string artistName)
{
var artistMatches = GetPossibleArtists(artistName);
if (artistMatches.Count() == 0)
return null;
return artistMatches.First();
}
So that I first access the database to find the artist by its ID because I can't simply find albums by the artist's name, because the artist's name is not a primary key and I can't search the "Albums" table by the artist's name, I can only search this table by the artist's ID
And then I can finally find all the albums by the artist's id
public static IQueryable<Album> GetPossibleAlbums(long artistID)
{
var matches = from match in dB.Albums where
match.ArtistID == artistID
select match;
return matches;
}
The questions are :
1) What am I doing wrong here and is there a better way to access all the albums of an artist so that I do not need to access the database to "find the ID of an artist by its name" first before I manage to find all the albums by the artistID?
2) I could possibly design my database wrong, are there any suggestions?
3) Is it a good idea to store the artist's name inside of the "Album" table and how do I need to do this to keep my Artist's autoincrement primary key exist at the same time?
You need a JOIN to associate the Albums table to the Artists table on the ArtistID field
var matches = from a in dB.Albums join b in db.Artists on a.ArtistID equals b.ArtistID
where b.ArtistName == artistName
select a;
join clause C# reference

Retrieve foreign key values in Linq

I have 2 tables
User
Access
In the user table I have 4 columns in total but 1 in foreign key of another table (Access).
UserId
UserName
UserEmail
AccessId(FK)
And in the Access table I have 2 columns
AccessId
Yes/NO
I'm able to retrieve the UserId but not AccessId because it is a foreign key in User table.
Here is the code I have written
var test = (from userName in User
select userName.AccessId).ToList();
This is the result I get
System.Collections.Generic.List`1
I want to get the AccessId as well, can you help me please?
Well
var test = (from userName in User
select userName.AccessId).ToList();
Returns a list, so that is what you get. A list of AccessID's.
If you need the ID;s
foreach (var aSingleAccessID in test)
{
// do something with each accessID
}

asp.NET LINQ Delete from database

I have a SQL Server database with 2 tables:
t1 - Category
Id
Name
t2- Product
Id
Name
CategoryId
I want to delete a row from the Category table, but since I have the foreign key I need to handle the products that has the CategoryId I want to delete.
So I did this:
var ProdCatID = (from prod in DataContext.Products
where prod.CategoryId == Convert.ToInt32(Id)
select prod).First();
ProdCatID.CategoryId = null;
DataContext.SubmitChanges();
var DelCat = (from cat in DataContext.Categories
where cat.Id == Convert.ToInt32(Id)
select cat).ToList();
DataContext.Categories.DeleteAllOnSubmit(DelCat);
DataContext.SubmitChanges();
What Im trying to do is to check if there is any product with thatCategoryId, if there is - I want to set theCategoryIDto null and then delete the row from theCategory` table.
It is working when I have a product with a CategoryId but when I can't delete it.
Any ideas?
You're only setting the first product that has this CategoryID to null - you need to handle all products that have that ID !
var products = (from prod in DataContext.Products
where prod.CategoryId == Convert.ToInt32(Id)
select prod).ToList();
foreach(Product p in products)
{
p.CategoryId = null;
}
DataContext.SubmitChanges();
.....
After that, now you should be able to delete the category from the table
Simple!
Change the Product table configuration in Database!
ALTER TABLE Product
ADD CONSTRAINT 'Category_FK'
FOREIGN KEY (CategoryId)
REFERENCES Category(Id)
ON DELETE SET NULL;
whenever you delete a primary key will automatically put null!
Cascade on Delete is there in entity framework. Cascade delete automatically deletes dependent records or set null to foreignkey properties when the principal record is deleted.
This is one to many reletionship between parent and child
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>()
.HasOptional(a => a.UserDetail)
.WithOptionalDependent()
.WillCascadeOnDelete(true);
}
For more details check this: http://www.entityframeworktutorial.net/code-first/cascade-delete-in-code-first.aspx

DeleteObject from multiple tables

I am trying to delete the movie from rentals table if it is selected from the listbox and it is working but i also need to remove datas connected to the movie from rentingpeople table
Rentals table contains the movieid which is in the listobox and personid which can be also found in rentingpeople and should get deleted the full row if they matches.
var search = (from g in db.Rentals where g.Movietitle == (string)lBfilmlista.SelectedValue select g).First();
foreach (var c in db.Rentingpeople where c.personid==search.personid).First();
{
db.Rentingpeople.DeleteObject(c);
}
db.Rentals.DeleteObject(search);
db.SaveChanges();
there is code error at where c.personid==search.personid ) ; expected
Problem is with First at the end of foreach loop, and also mixing query syntax with method syntax.
So your code should be:
var search = (from g in db.Rentals where g.Movietitle == (string)lBfilmlista.SelectedValue select g).First();
var rowsToBeDeleted = db.Rentingpeople.Where(c=> c.personid==search.personid).ToList();
foreach (var item in rowsToBeDeleted)
{
db.Rentingpeople.DeleteObject(item);
}
db.Rentals.DeleteObject(search);
db.SaveChanges();
You can also setup Cascade on Delete rules for your tables.

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

Categories