How to delete in linq to sql? - asp.net

I am very new to linq to sql and I am not sure how to actually delete a record.
So I been looking at this tutorial
http://weblogs.asp.net/scottgu/archive/2007/05/19/using-linq-to-sql-part-1.aspx
So for Update they have
NorthwindDataContext db = new NorthwindDataContext();
Product product = db.Products.Single(p => p.ProductName == "Toy 1");
product.UnitPrice == 99;
product.UnitsInStock = 5;
db.SubmitChanges();
For delete they have
NorthwindDataContext db = new NorthwindDataContext();
var toyProducts = from p in db.Producsts
where p.ProductName.Contains("Toy")
select p;
db.Products.RemoveAll(toyProducts);
db.SubmitChanges();
So do I have to query every time, to get the record in order to delete that record? Like I can sort of see doing this with update since you need to give it a record which to update first and then make the changes so I understand the querying part but not with delete.
Like can't you just send in what you want to delete and it goes and deletes it? why do you have to first get it and then tell it to be deleted?
Is that not 2 hits on the database?
Also I have foreign key relationship that I am trying to get to work. So I have this
public ViewResult(string param1, string param2)
{
Table A = new Table A
A.Field1 = param1;
A.Field2 = param2;
Delete(A);
}
private void Delete(Table A)
{
DbContext.A.DeleteAllOnsubmit(A.TableB);
DbContext.A.DeleteAllOnSubmit(A.TableC);
DbContext.A.DeleteOnSubmit(A);
}
So this fails it comes up with this message "Cannot remove an entity that has not been attached."
So I can see why the first 2 lines would fail in the delete method, since I made a new object and their is nothing in the object that has any information about TableB and TableC.
I however can't see why the last line still fails even if the 2 other lines where not there.
Like how I thought it would work it would take my Table A class object that I passed in and look through the table for that information contained in it. It does not seem to be the case though.
So do I first have to take the information out and then do a query to get it and then delete it, like in the example?
Also what is the difference between removeAll() and say DeleteAllOnSubmit().
Like I said I am new to linq to sql and have not been able to sit down and read a book on it due to time constraints. Once I have more time I will read through a book probably.
Thanks

You have several questions in your one question, but I will start with the simplest, about attaching, if you already have the primary key. If you don't have the primary key then I have always just done a fetch then a delete, but, whenever I do a fetch I tend to store the primary key for updates and deletes.
It will delete off of the primary key, but if you have that then just attach as I do below and call delete. I don't pass around the object needed by DLINQ as I want to be able to change it if I want, so I pass in a different User object and just pull the PK from the business class and put it into the DAO class.
var db = new MeatRequestDataContext();
if (input.UserID > 0)
{
entity = new User()
{
UserID = input.UserID
};
db.Users.Attach(entity);
db.Users.DeleteOnSubmit(entity);
}

this is a simple way to delete row from table by linq query.may be it helps .
var summary_delete = database.summeries.Find(id);
var delete = database.summeries.Remove(summary_delete);
database.SaveChanges();
reference : http://mvc4asp.blogspot.in/2013/09/how-to-delete-table-row-in-sql-database.html

Inserted_LINQDataContext db = new Inserted_LINQDataContext();
Item itm = new Item();
int ID = Convert.ToInt32(TextBox1.Text);
var DeleteID = from d in db.Items
where d.id == ID
select d;
db.Items.DeleteAllOnSubmit(DeleteID);
db.SubmitChanges();
Label2.Text = "Record deleted Successfully.";
TextBox1.Text = "";
where Item is Table name, Linserted_LINQDataContext is your Linq DB name, id is the Column name in Item table. Items is the alias name of Item table in linq.

SupportDataDataContext Retrive = new SupportDataDataContext();
// SupportDataDataContext delete = new SupportDataDataContext();
Topic res = Retrive.GetTable<Topic>().Single(t => t.ID == topicID);
if (res != null)
{
Retrive.Topics.DeleteOnSubmit(res);
Retrive.SubmitChanges(ConflictMode.ContinueOnConflict);
}

I know the question is old but this may be useful to someone:
"YourDataContext" dc = new "yourDataContext";
"YourTable" element = dc."YourTable".First(a => a.Id == 12345);
dc."YourTable".DeleteOnSubmit(element);
dc.SubmitChanges();

Related

Removing item from list in EF model

I'm using Entity Framework and I am trying to remove a NinjqEquiment from a list belonging to an instance of Ninja.When I retrieve the list of Ninjas,I make sure to include the equipment list, so I know they are there. Then I remove the equipment from the Ninja and try to save changes. I get the following error -
The entity type List`1 is not part of the model for the current
context.
using (var db = new NinjaDbContext())
{
//get ninjas with equipment included
var ninjas = GetAllNinjas();
//get ninja
var ninja = (from n in ninjas
where n.Id == id
select n).FirstOrDefault();
//get equipment
var eq = (from e in ninja.EquipmentOwned
where e.Id == removeEqId
select e).FirstOrDefault();
//remove eq from ninja
ninja.EquipmentOwned.Remove(eq);
//Make sure entity knows EquipmentOwned has been modified
db.Entry(ninja.EquipmentOwned).State = EntityState.Modified;
//save ninja
db.SaveChanges();
}
Just remove this:
//Make sure entity knows EquipmentOwned has been modified
db.Entry(ninja.EquipmentOwned).State = EntityState.Modified;
This causes the error.
EquipmentOwned is a List<Equipment>. It is not an Entry in EF terms so it is not tracked directly by it.
When you delete an entity from such collection, EF knows that there won't be any relationship between this particular ninja and this particular equipment. It won't delete equipment from database because other ninjas may use this equipment.
To delete it completely you should remove this equipment from corresponding DbSet<> like this:
using (var db = new NinjaContext())
{
//db.Equipment is a DbSet<Equipment>
//id is PrimaryKey of Equipment table
var eq = db.Equipment.Find(id);
db.Equipment.Remove(eq);
db.SaveChanges();
}

How to pick recently inserted record id of the current session?

I am using ASP.NET 4.0 with SQL Server 2008 R2 and PetaPoco ORM.
A Web Form consists of Tab Panels, for example:
-- Employee General Information
-- Appointment
-- Education
Each Tab Panel entry goes to a specific table in SQL Server. I have a main table, employee, with Primary Key empID. Other tables, viz., appointment, education etc. are related with empID.
I have multiple methods to Save record in respective tables:
AddGeneralInformation saves the General Information Tab Panel record.
AddAppointment saves the appointment details and so on.
The application is being used in a concurrent environment where multiple users are either inserting or updating records.
For the second and third methods to insert a new record, the methods must have the correct empID. As soon as the first method (General Information) saves the record, the empID is to be used in other methods.
The problem is that if I use:
Select max(empID)
then it won't pick the correct empID as many users are inserting records.
On solution I feel is to use another column containing SessionID and use this query:
Select max(empID) where sessionID = SessionID
Is there any more reliable way to do this?
** Edited **
protected void btnSave_Click(object sender, EventArgs e)
{
Session.Add("TaskFlag", "New");
AddUpdateEmployee();
AddUpdateAddress();
}
protected void AddUpdateEmployee()
{
var db = new PetaPoco.Database("cnWeb");
var emp = new employee(); */
using (TransactionScope scope = new TransactionScope())
{
db.BeginTransaction();
emp.deptcode = txtEmpCode.Text.TrimEnd();
emp.empname = txtEmpName.Text.TrimEnd();
emp.guardianname = txtGuardian.Text.TrimEnd();
emp.relationwithemployee = ddlRelation.Text.TrimEnd();
emp.gender = ddlGender.SelectedItem.Text;
emp.dateofbirth = Convert.ToDateTime(txtDOB.Text.TrimEnd());
if (Session["TaskFlag"].ToString() == "New")
db.Insert(emp);
else if (Session["TaskFlag"].ToString() == "Update")
db.Update<employee>("SELECT * FROM employee WHERE empid = #0", Session["EmployeeID"]);
reuse.CustomClientMessage("Record Saved", this.Page);
ClearFields();
/* Commit Transaction */
db.CompleteTransaction();
scope.Complete();
}
}
protected void AddUpdateAddress()
{
var db = new PetaPoco.Database("cnWeb");
var addr = new emp_address();
using (TransactionScope scope = new TransactionScope())
{
db.BeginTransaction();
/* Permanaent Address */
addr.perm_houseno = txtPermHouse.Text.TrimEnd();
addr.perm_street = txtPermStreet.Text.TrimEnd();
addr.perm_place = txtPermCity.Text.TrimEnd();
addr.perm_pincode = txtPermPincode.Text.TrimEnd();
addr.perm_landlinephone = txtPermLandline.Text.TrimEnd();
addr.perm_mobilephone = txtPermMobile.Text.TrimEnd();
if (Session["TaskFlag"].ToString() == "New")
db.Insert(addr);
else if (Session["TaskFlag"].ToString() == "Update")
db.Update<emp_address>("SELECT * FROM emp_address WHERE empid = #0", Session["EmployeeID"]);
/* Commit Transaction */
db.CompleteTransaction();
scope.Complete();
}
}
Best solution: make your EmpID column an INT IDENTITY in SQL Server and let the database handle the details.
Anything you dream up in code (T-SQL or C#) is most likely going to have some issues and won't work well under load - why not just use what's there, works, and is tested by hundreds of thousands of users?
Once you insert a row into a table with an INT IDENTITY column, you can fetch that value using
DECLARE #NewEmpID INT
SELECT #NewEmpID = SCOPE_IDENTITY()
or alternatively, you could use the OUTPUT clause on your INSERT statement
INSERT INTO dbo.YourTableHere(List of columns)
OUTPUT Inserted.EmpID
VALUES(list of value here)
create a new column like created_datewith datetime in the table Employee General Information and get the latest record.
Try this Procedure
create Procedure Get_LastRow
(
-- Table name to retrieve last record
#Tname Varchar(50)
)
AS
BEGIN
EXECUTE ('DECLARE GETLAST CURSOR DYNAMIC FOR SELECT * FROM ' + #Tname)
OPEN GETLAST
FETCH LAST FROM GETLAST
CLOSE GETLAST
DEALLOCATE GETLAST
END
Execute the procedure like this.
EXEC Get_LastRow 'dbo.TableA'
Just after the Insert query, you the SELECT ##IDENTITY. You field EmpID need to be a IDENTITY TO work.

Linq to entity delete a specific column from a table

Linq to entity query to delete a specific column from a table by matching a condition`
public ActionResult deleteChecks(string checkValue)
{
check_master checks = (from table in db.check_master
where table.check_code == checkValue
select table).First();
//now how to delete/remove checks.mcheck
return View("Edit");
}`
Only want to update a single column element with null value(of selected row) from the table check_master
You can set a single property (which maps to a column) to null and save it to the database
foreach(check_master check in checks)
{
check.mcheck = null;
}
db.SaveChanges();
using (NorthwindDataContext db = new NorthwindDataContext())
{
// Retrieve the existing entity. Database Call 1
Product product = db.Products.First(p => p.ProductID == 1);
// Change the properties. LINQ to SQL knows
// these specific properties have changed.
product.UnitsInStock = 14;
// Flush the changes. Database Call 2
db.SubmitChanges();
}
Entity framework works with constant table scheme only.
Tell please, what your global aim is, may be there's some more suitable way to do it.
Updated:
foreach(var chm in db.check_master)
{
chm.mcheck = null;
}
db.SaveChanges();
I believe that Linq to Entities only support DML, it does not support DDL operations.
So you would have to use stored procedure or ADO.NET raw query.
EDIT
you can do simple update like this :
public ActionResult deleteChecks(string checkValue)
{
check_master checks = (from table in db.check_master
where table.check_code == checkValue
select table).First();
checks.mcheck = null;
db.SaveChanges();
return View("Edit");
}`

Returning a column from a linked table in LINQ to SQL

My problem is that I am trying to return a simple query that contains an object Story. The Story object has a UserId in the table which links to aspnet_users' UserId column. I have created a partial class for Story that adds the UserName property since it does not exist in the table itself.
The following query gets all stories; however, a pagination helper takes the query and returns only what's necessary once this is passed back to the controller.
public IQueryable<Story> FindAllStories(){
var stories = (from s in db.Stories
orderby s.DateEntered descending
select new Story
{
Title = s.Title,
StoryContent = s.StoryContent,
DateEntered = s.DateEntered,
DateUpdated = s.DateUpdated,
UserName = s.aspnet_User.UserName
}
);
return stories;
}
When the helper does a .count() on the source it bombs with the following exception:
"Explicit construction of entity type 'MyWebsite.Models.Story' in query is not allowed."
Any ideas? It's not a problem with the helper because I had this working when I simply had the UserName inside the Story table. And on a side note - any book recommendations for getting up to speed on LINQ to SQL? It's really kicking my butt. Thanks.
The problem is precisely what it tells you: you're not allowed to use new Story as the result of your query. Use an anonymous type instead (by omitting Story after new). If you still want Story, you can remap it later in LINQ to Objects:
var stories = from s in db.Stories
orderby s.DateEntered descending
select new
{
Title = s.Title,
StoryContent = s.StoryContent,
DateEntered = s.DateEntered,
DateUpdated = s.DateUpdated,
UserName = s.aspnet_User.UserName
};
stories = from s in stories.AsEnumerable() // L2O
select new Story
{
Title = s.Title,
StoryContent = s.StoryContent,
...
};
If you really need to return an IQueryable from your method and still need the Username of the user you can use DataContext.LoadOptions to eagerload your aspnet_user objects.
See this example.

Issue with LINQ to SQL insert . .

i was looking at an example of how to do an insert in Linq to SQL and here it was it said:
NorthwindDataContext context = new NorthwindDataContext();
context.Products.Add(new Product(..));
context.SubmitChanges();
but when i look at the below, (in my case the Table is UserInfo), the Table doesn't have an "Add" method:
public System.Data.Linq.Table<UserInfo> UserInfos
{
get
{
return this.GetTable<UserInfo>();
}
}
any clue what i am doing wrong here?
You should use the InsertOnSubmit method:
NorthwindDataContext context = new NorthwindDataContext();
context.Products.InsertOnSubmit(new Product(..));
context.SubmitChanges();
The Add method exist on the EntitySet members, is mostly used when adding Child entities to a Parent one, for example:
var category = new Category{ Name = "Breveages"};
category.Products.Add(new Product{ Name = "Orange Juice"});
category.Products.Add(new Product{ Name = "Tomato Juice"});
category.Products.Add(new Product{ Name = "Cola"});
//...
context.Categories.InsertOnSubmit(category);
// This will insert the Category and
// the three Products we associated to.
EDIT: To do update operations, you just need to retrieve the entity by doing a query, or attaching it, for example:
var customer = context.Customers.Single( c => c.CustomerID == "ALFKI");
customer.ContactName = "New Contact Name";
context.SubmitChanges();
The DataContext tracks the changes of its related entities and when the SubmitChanges method is called, it will detect that change, and generate an Update SQL statement behind the scenes to do the update operation...

Resources