Do not find DeleteOnSubmit method - c#

Im want to delete rows from a table that in my data base.
i have the member
private static WeightScaleEntities Weight = new Weight();
this member contains my database. in the data base i have table: User_Activity.
I want to delete rows from user activity by given i_UserActivityId, as follow:
//Get the rows for delete
var deleteUserActivities = from details in Weight.User_Activity
where details.Id == i_UserActivityId
select details;
Now i want to delete this rows, so i tried to do:
foreach (var item in deleteUserActivities)
{
m_WeightScaleEntities.User_Activity.*
}
and i dont get the method DeleteOnSubmit!
Why?
there is another option???

User_Activity.*: is that a typo?
What I think you want is:
foreach (var item in deleteUserActivities)
{
Weight.DeleteObject(item);
}
And then SaveChanges() on the object context.
BTW, a static object context is not a good idea. You should carefully control the life cycle of object contexts.

There is more than one way to execute deletion in Entity Framework,
You must take into account what are the values that you want to delete? one Row or more.
when you need to delete on Row from table we can use these ways:
// first way
using (WeightScaleEntities db = new WeightScaleEntities())
{
var deleteUserActivities = from details in db.User_Activity
where details.Id == i_UserActivityId
select details;
if (deleteUserActivities.Count() > 0)
{
db.deleteUserActivities.Remove(deleteUserActivities.First());
db.SaveChanges();
}
}
this line deleteUserActivities.Count()>0 to check if you have result in the Query or not.
and this deleteUserActivities.First() if the query return set of rows delete the first. "to make the process more secure if you don't know about the data in the table"
// second way
using (WeightScaleEntities db = new WeightScaleEntities())
{
var deleteUserActivities = (from details in db.User_Activity
where details.Id == i_UserActivityId
select details).SingleOrDefault();
if (deleteUserActivities != null)
{
db.User_Activity.Remove(deleteUserActivities);
// or use this line
//db.Entry(deleteUserActivities).State = System.Data.Entity.EntityState.Deleted;
db.SaveChanges();
}
}
You can also use Single or SingleOrDefault to get a single object. Single or SingleOrDefault will throw an exception, if the result contains more than one element. Use Single or SingleOrDefault where you are sure that the result would contain only one element. If the result has multiple elements then there must be some problem.
Also, if you need to remove one or multi rows use this way:
using (WeightScaleEntities db = new WeightScaleEntities())
{
var deleteUserActivities = (from details in db.User_Activity
where details.Id == i_UserActivityId
select details).ToList<User_Activity>(); //<User_Activity> her name of your DbSet
foreach(deleteObject in deleteUserActivities)
{
db.Entry(deleteObject).State = System.Data.Entity.EntityState.Deleted;
}
db.SaveChanges();
}
Best Regards
and sorry about English language.

using(WeightScaleEntities db=new WeightScaleEntities())
{
var deleteUserActivities = from details in db.User_Activity
where details.Id == i_UserActivityId
select details;
if (deleteUserActivities.Count()>0)
{
db.deleteUserActivities.Remove(deleteUserActivities.First());
db.SaveChanges();
}
}

Related

Linq Query on DataTable and Update Records

I have a datatable in memory and I need to select some records from it, walk through the records making changes to fields and they same the changes back to the datatable. I can do this with filters, views, and sql but I'm trying to do it in Linq.
var results = (from rows in dtTheRows.AsEnumerable()
select new
{
rows.Job,
}).Distinct();
foreach (var row in results)
{
firstRow = true;
thisOnHand = 0;
var here = from thisRow in dtTheRows.AsEnumerable()
orderby thisRow.PromisedDate
select new
{
thisRow.OnHandQuantity,
thisRow.Balance,
thisRow.RemainingQuantity
};
foreach(var theRow in here)
{
// business logic here ...
theRow.OnHandQuantity = 5;
} // foreach ...
The first linq query and foreach are gain the list of subsets of data to be considered. I include it here in case it is relevant. My problem is at this line:
heRow.OnHandQuantity = 5;
My error is:
"Error 19 Property or indexer 'AnonymousType#1.OnHandQuantity' cannot be assigned to -- it is read only"
What am I missing here? Can I update this query back into the original datatable?
var here = from thisRow in dtTheRows.AsEnumerable()
orderby thisRow.PromisedDate
select new
{
thisRow.OnHandQuantity,
thisRow.Balance,
thisRow.RemainingQuantity
};
Instead of passing three variables in select, pass thisRow itself. That may solve error on statement - theRow.OnHandQuantity = 5;
The error is self descriptive, you can't update/modify an anonymous type. You have to return the original entity you want to modify from your query.
select thisRow;
instead of
select new
{
thisRow.OnHandQuantity,
thisRow.Balance,
thisRow.RemainingQuantity
};

insert multiple records one by one using LINQ

I'm trying to copy ProductStatisticsTemp table data to ProductStatistics table,
var str = from a in db.ProductStatisticsTemp select a;
ProductStatistics ls = new ProductStatistics();
foreach (var val in str.ToList())
{
ls.Product_ID = val.Product_ID;
ls.ProductNameEn = val.ProductNameEn;
ls.ProductNameAr = val.ProductNameAr;
db.ProductStatistics.Add(ls);
db.SaveChanges();
}
first record can insert but once its try to insert 2nd one getting following error
The property 'Product_ID' is part of the object's key information and
cannot be modified.
It's because you have one instance of an object and try to add already added object twice.
You need to create new object of ProductStatistics in the loop.
Also you can save changes just once after the loop to improve performance by trigger DB communication just once:
var str = from a in db.ProductStatisticsTemp select a;
foreach (var val in str.ToList())
{
ProductStatistics ls = new ProductStatistics
{
Product_ID = val.Product_ID,
ProductNameEn = val.ProductNameEn,
ProductNameAr = val.ProductNameAr
};
db.ProductStatistics.Add(ls);
}
db.SaveChanges();
Here is a slightly different method.
var products = db.ProductStatisticsTemp.Select(t => new ProductStatistics
{
Product_ID = t.Product_ID,
ProductNameEn = t.ProductNameEn,
ProductNameAr = t.ProductNameAr
}).ToList()
db.ProductStatistics.AddRange(products);
db.SaveChanges();
IMHO Inspired from #Vadim Martynov
If the Product_ID is your primary key, and your set to increment
the key from database . Do not do this Product_ID = val.Product_ID.
The key should be generated from the database. You will get the id
after save changes is invoked.
try
{
var str = from a in db.ProductStatisticsTemp select a;
//This will improve some performance
db.Configuration.AutoDetectChangesEnabled = false;
foreach (var val in str.ToList())
{
ProductStatistics ls = new ProductStatistics
{
Product_ID = val.Product_ID,
ProductNameEn = val.ProductNameEn,
ProductNameAr = val.ProductNameAr
};
//use AddRange or Add based on your EF Version.
db.ProductStatistics.Add(ls);
}
db.SaveChanges();
}
finally
{
db.Configuration.AutoDetectChangesEnabled = true;
}
If you are using AddRange you could omit db.Configuration.AutoDetectChangesEnabled = false
For more info about DetectChanges available here
AddRange() method only support from EF6 see documentation
db.ProductStatistics.AddRange(products);
What AddRange will do for you is
if AutoDetectChangesEnabled is set to true (which is the default), then DetectChanges will be called once before adding any entities and will not be called again.
This means that in some situations AddRange may perform significantly
better than calling Add multiple times would do.
Note that entities that are already in the context in some other state will have their state set to Added. AddRange is a no-op for entities that are already in the context in the Added state.

How can I edit or add to a particular field without pull the all object

How I can do just this ( a.myFavorits.Add()) without pulling the all object to var a , because a has a lot of data, and I don't want to pull all a object, but I can't find a way do do it.
I want to do the lambada and the linq without return something but linq is always return something
public static void addFavorits(long f,long idUser)
{
using (var db = dataBase())
{
// here i pull object user from users table
var a = db.users.Where(c => c.id == idUser).SingleOrDefault();
// here i adding to the object field myFavorits new value
//myFavorits is also a table of entitys that connected to user object
a.myFavorits.Add(new BE.FavoritsUsersLong { myLong = f });
db.SaveChanges();
}
}
I thought to do something like this but i dont know how to set the field users_TableId that is the key that connect the 2 tables
public static void addFavorits(long favoritId,long idUser)
{
using (var db = dataBase())
{
db.favoritsUsersLong.Add(new BE.FavoritsUsersLong {myLong = favoritId}
/*,users_TableId =idUser*/);
db.SaveChanges();
}
}
Here's a concrete example that does what you want. In this example, only the Name of a Company is modified and saved. Or an item is added to one of its collections.
var cmp = new Company{ CmpId = 1, Name = "Cmp1" }; // CmpId is the primary key
db.Companies.Attach(cmp);
db.Entry(cmp).Property(c => c.Name).IsModified = true;
// Or add an entity to a collection:
cmp.Users = new[] {new User { Name = "a1", PassWord = "a1" } };
try
{
db.Configuration.ValidateOnSaveEnabled = false;
db.SaveChanges();
}
finally
{
db.Configuration.ValidateOnSaveEnabled = true;
}
Result in SQL:
DECLARE #0 VarChar(30) = 'Cmp1'
DECLARE #1 Int = 1
UPDATE [dbo].[Company]
SET [Name] = #0
WHERE ([CmpId] = #1)
There are a few things to note here:
Obviously you need to know the Id of the entity you want to modify.
The object you create is called a stub entity, which is an incomplete entity. When you try to save such an entity, EF is very likely to complain about null values in required properties. That's why almost certain you'd have to disable validation (temporarily, or, better, dispose the context immediately).
If you want to add an item to a collection, you should leave validation enabled, because you'd want to know for sure that the new entity is valid. So you shouldn't mix these two ways to use a stub entity.
If you often need roughly the same small part of your entity you may consider table splitting.
I'm guessing this is what you want? I don't see you 'editting' I only see you adding.
using (var db = dataBase())
{
var a = new user();
....
//set properties etc..
...
a.myFavorits.Add(new BE.FavoritsUsersLong { myLong = f });
db.users.Add(a);
db.SaveChanges();
}

Updating a record using LINQ Context?

i am trying to update a user table with a single value update, but i can't figure out what i'm doing wrong. this is what i have:
public static void ApplyROB(string ROBread, string userName)
{
using (SERTEntities ctx = CommonSERT.GetSERTContext())
{
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
// Audit of the transfer
datUser trUser = new datUserRole();
trUser.ROB = ROBread;
trUser.AccountName = userName;
// Persist update to DB
ctx.SaveChanges();
}
}
am i way off? nothing happens when i click on the update.
how do i say, where username = username? did i do it right?
basically in need a simple:
update datUser set ROB = "Y" where AccountName= "myusername"
it's turning out to be a bit more complicated in LINQ using Context
please help.
You're not adding your new entity to the context, thus when you save, the context is unaware of any changes. You need something like...
ctx.datUserRoles.Add(datUserRole)
To do an update, you need to retreive an entity from the context, make changes to it, then save... so:
var entity=ctx.datUserRoles.SingleOrDefault(dur=>dur.AccountName==someUserName);
if(entity!=null)
{
entity.someProp=someVal;
ctx.SaveChanges();
}
else
{
throw new UnexpectedOperationException(); //or however you want to fail
}
If you need an update. Maybe something like this:
public static void ApplyROB(string ROBread, string userName)
{
using (SERTEntities ctx = CommonSERT.GetSERTContext())
{
var trUser= ctx.datUserRole.Where(a=>a.AccountName==userName)
.FirstOrDefault();
if(trUser!=null)
{
trUser.ROB = ROBread;
ctx.SaveChanges();
}
}
}
If you are sure that you will always have something to update you can use First(). Then you do not need to check if the trUser is null
spender is correct in a sense, incorrect in another: you want to update an existing record.
For that you'll need to select the record first, for instance:
var user =
(from u in ctx.datUserRoles
where u.AccountName == "accountname"
select u).FirstOrDefault();
Where accountname is a valid thing of the same type - that doesn't matter, since you can select it how you want, you can touch that up to meet your criteria. Then once you have the item do the stuff:
if (user != null) {
user.ROB = ROBread;
ctx.SaveChanges();
}

Newbie performance issue with foreach ...need advice

This section simply reads from an excel spreadsheet. This part works fine with no performance issues.
IEnumerable<ImportViewModel> so=data.Select(row=>new ImportViewModel{
PersonId=(row.Field<string>("person_id")),
ValidationResult = ""
}).ToList();
Before I pass to a View I want to set ValidationResult so I have this piece of code. If I comment this out the model is passed to the view quickly. When I use the foreach it will take over a minute. If I hardcode a value for item.PersonId then it runs quickly. I know I'm doing something wrong, just not sure where to start and what the best practice is that I should be following.
foreach (var item in so)
{
if (db.Entity.Any(w => w.ID == item.PersonId))
{
item.ValidationResult = "Successful";
}
else
{
item.ValidationResult = "Error: ";
}
}
return View(so.ToList());
You are now performing a database call per item in your list. This is really hard on your database and thus your performance. Try to itterate trough your excel result, gather all users and select them in one query. Make a list from this query result (else the query call is performed every time you access the list). Then perform a match between the result list and your excel.
You need to do something like this :
var ids = so.Select(i=>i.PersonId).Distinct().ToList();
// Hitting Database just for this time to get all Users Ids
var usersIds = db.Entity.Where(u=>ids.Contains(u.ID)).Select(u=>u.ID).ToList();
foreach (var item in so)
{
if (usersIds.Contains(item.PersonId))
{
item.ValidationResult = "Successful";
}
else
{
item.ValidationResult = "Error: ";
}
}
return View(so.ToList());

Categories

Resources