asp.NET LINQ Delete from database - c#

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

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
)
)
}).

C# Linq DeleteObject

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

How to write linq query comparing 2 tables?

Okay so I have a database that has a Projects, Users and ProjectMembers table, the Projects table has an ID column and ProjectOwner column which is a foreign key from the Users table, the Users table has ID, username columns and the ProjectMembers table has an ID, ProjectID and UserID column with the later 2 columns being foreign keys from the Projects table and Users table.
Basically the project is something that manages projects, a user can create a project which makes them the owner and then other users can be assigned to that project which adds a record to the ProjectMembers table.
I'm trying to write a linq query that selects all records from the Projects table where a specific user isn't the ProjectOwner but they are a ProjectMember in the ProjectMembers table?
I've made various attempts but so far haven't been able to get the query right.
Something like this should work:
from p in Projects
join m in ProjectMembers on m.ProjectID equals p.ID
where m.UserID == userID && p.ProjectOwner != userID
group p by p.ID
select p
You can make several from clauses:
from e1 in table1
from e2 in table2
where e1.key == e2.id
select e1.name
Try this:
from x in Users
where ProjectMembers.Any(y => y.UserID==x.ID) &&
!ProjectOwners.Any(z => z.ProjectOwner==x.ID)
select x;

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

C# - Entity Framework inserting

I have two tables Category and Product and I would like to insert products into categories. The table relation between these tables is one to zeor or one.
Category table:
CID : integer,
CategoryName : varchar,
Product table:
CID: integer, // foreign key to category table.
ProductName: varchar,
UnitsInstock: integer,
How can I write a simple query for inserting a product into the ProductTable? How do I handle the foriegn key situation? If the categoryid does not exists then the product should not be inserted.
I would realy appreciate any kinds of help.
One approach could be this one:
int categoryIdOfNewProduct = 123;
using (var context = new MyContext())
{
bool categoryExists = context.Categories
.Any(c => c.Id == categoryIdOfNewProduct);
if (categoryExists)
{
var newProduct = new Product
{
Name = "New Product",
CategoryId = categoryIdOfNewProduct,
// other properties
};
context.Products.Add(newProduct); // EF 4.1
context.SaveChanges();
}
else
{
//Perhaps some message to user that category doesn't exist? Or Log entry?
}
}
It assumes that you have a foreign key property CategoryId on your Product entity. If you don't have one please specify more details.
Normally a category to product would be many to one, but I would suggest studying the basics of Linq to Sql first:
http://msdn.microsoft.com/en-us/library/bb425822.aspx
Linq to Sql 101
Learn the Entity Framework

Categories