Update using LINQ to SQL - linq

How can I update a record against specific id in LINQ to SQL?

LINQ is a query tool (Q = Query) - so there is no magic LINQ way to update just the single row, except through the (object-oriented) data-context (in the case of LINQ-to-SQL). To update data, you need to fetch it out, update the record, and submit the changes:
using(var ctx = new FooContext()) {
var obj = ctx.Bars.Single(x=>x.Id == id);
obj.SomeProp = 123;
ctx.SubmitChanges();
}
Or write an SP that does the same in TSQL, and expose the SP through the data-context:
using(var ctx = new FooContext()) {
ctx.UpdateBar(id, 123);
}

In the absence of more detailed info:
using(var dbContext = new dbDataContext())
{
var data = dbContext.SomeTable.SingleOrDefault(row => row.id == requiredId);
if(data != null)
{
data.SomeField = newValue;
}
dbContext.SubmitChanges();
}

AdventureWorksDataContext db = new AdventureWorksDataContext();
db.Log = Console.Out;
// Get hte first customer record
Customer c = from cust in db.Customers select cust where id = 5;
Console.WriteLine(c.CustomerType);
c.CustomerType = 'I';
db.SubmitChanges(); // Save the changes away

DataClassesDataContext dc = new DataClassesDataContext();
FamilyDetail fd = dc.FamilyDetails.Single(p => p.UserId == 1);
fd.FatherName=txtFatherName.Text;
fd.FatherMobile=txtMobile.Text;
fd.FatherOccupation=txtFatherOccu.Text;
fd.MotherName=txtMotherName.Text;
fd.MotherOccupation=txtMotherOccu.Text;
fd.Phone=txtPhoneNo.Text;
fd.Address=txtAddress.Text;
fd.GuardianName=txtGardianName.Text;
dc.SubmitChanges();

I found a workaround a week ago. You can use direct commands with "ExecuteCommand":
MDataContext dc = new MDataContext();
var flag = (from f in dc.Flags
where f.Code == Code
select f).First();
_refresh = Convert.ToBoolean(flagRefresh.Value);
if (_refresh)
{
dc.ExecuteCommand("update Flags set value = 0 where code = {0}", Code);
}
In the ExecuteCommand statement, you can send the query directly, with the value for the specific record you want to update.
value = 0 --> 0 is the new value for the record;
code = {0} --> is the field where you will send the filter value;
Code --> is the new value for the field;
I hope this reference helps.

Related

Convert if and foreach statement to select and where in linq

How would I go about changing my if statement and foreach to something cleaner in linq using select and where.
I've tried to make the if statement into a where clause and then use the select query as a replacement for the Foreach loop but that seem to have type issues and wasn't working.
{
StripeConfiguration.ApiKey = _appSettings.StripeSecretKey;
var profile = await _userManager.FindByIdAsync(customerServiceID);
var stripeId = profile.StripeAccountId;
if (stripeId == null)
throw new ArgumentException("No associated Stripe account found.");
List<PaymentMethodDto> result = new List<PaymentMethodDto>();
var options = new PaymentMethodListOptions
{
Customer = stripeId,
Type = "card",
};
var service = new PaymentMethodService();
var payments = await service.ListAsync(options);
if (payments != null && payments.Data?.Count > 0)
{
payments.Data.ForEach((x) =>
{
result.Add(
new PaymentMethodDto
{
Brand = x.Card.Brand,
LastDigits = x.Card.Last4,
StripeToken = x.Id,
CustomerID = x.CustomerId
});
});
}
return result;
}
Just do a regular Select.
List<PaymentMethodDto> result = payments.Data.Select(x => new PaymentMethodDto
{
Brand = x.Card.Brand,
LastDigits = x.Card.Last4,
StripeToken = x.Id,
CustomerID = x.CustomerId
})
.ToList();
If payments.Data has nothing in it, this will give you an empty list, which is what you want.
If payments is null, you'll get an exception, which I think if you think about it really hard is probably what you really want in that case too. Why would .ListAsync() yield a null value?

How to: linq query

I am trying to get a record from database using linq but it keep return no record
it is very basic sql statment
select * where productid ='12553'
however the following code does not return any result. Please advise. thx you
private static IEnumerable<ProductModel> GetAllProduct(string productId)
{
using (var dc = new TestEntities())
{
var result = (from a in dc.Products
where a.productid == productId
select new ProductModel
{
ProductId = a.productid,
Name = a.ProductName
});
return result.Distinct().ToList();
}
}
You don't need projection here:
using (var dc = new TestEntities())
{
var result = from a in dc.Products
where a.productid == productId
select a;
return result.Distinct().ToList();
}

Error trying to loop through Linq query results

I need to pull any amount of records that correspond to a specific value (CourseCode), and insert these records into another table. This code works fine as long as the Linq code returns only one record, however if there is any more than that I get the following message:
An object with the same key already exists in the ObjectStateManager.
The existing object is in the Modified state. An object can only be
added to the ObjectStateManager again if it is in the added.
Below is my code:
if (_db == null) _db = new AgentResourcesEntities();
var prodCodes = from records in _db.CourseToProduct
where records.CourseCode == course.CourseCode
select records;
foreach (var pt in prodCodes.ToList())
{
agentProdTraining.SymNumber = symNumber;
agentProdTraining.CourseCode = course.CourseCode;
agentProdTraining.ProductCode = pt.ProductCode;
agentProdTraining.DateTaken = course.DateTaken;
agentProdTraining.Method = course.Method;
agentProdTraining.LastChangeOperator = requestor;
agentProdTraining.LastChangeDate = DateTime.Now;
agentProdTraining.DateExpired = course.ExpirationDate;
agentProdTraining.ProductCode = pt.ProductCode;
agentProdTraining.NoteId = pt.NoteId;
_db.AgentProductTraining.AddObject(agentProdTraining);
_db.SaveChanges();
PtAdded++;
EventLog.WriteEntry(sSource, "Product Training added", EventLogEntryType.Warning);
}
The loop is re-adding the same agentProdTraining object even though property values are changed. Create a new instance for each loop execution.
foreach (var pt in prodCodes.ToList())
{
var agentProdTraining = new AgentProductTraining();
agentProdTraining.SymNumber = symNumber;
agentProdTraining.CourseCode = course.CourseCode;
agentProdTraining.ProductCode = pt.ProductCode;
agentProdTraining.DateTaken = course.DateTaken;
agentProdTraining.Method = course.Method;
agentProdTraining.LastChangeOperator = requestor;
agentProdTraining.LastChangeDate = DateTime.Now;
agentProdTraining.DateExpired = course.ExpirationDate;
agentProdTraining.ProductCode = pt.ProductCode;
agentProdTraining.NoteId = pt.NoteId;
_db.AgentProductTraining.AddObject(agentProdTraining);
_db.SaveChanges();
PtAdded++;
EventLog.WriteEntry(sSource, "Product Training added", EventLogEntryType.Warning);
}

Problem returning an IEnumerable<T>/IList<T>

I am having trouble to return an IEnumerable and IList, I cant do it!
I am using EF 4 with POCOs
Here's the whole method:
//public IList<Genre> GetGenresByGame(int gameId)
public IEnumerable<Genre> GetGenresByGame(int gameId)
{
using(var ctx = new XContext())
{
var results =
from t0 in ctx.GameGenres
join t1 in ctx.GenreCultureDetails on t0.GenreId equals t1.GenreId
where t0.GameId == gameId && t1.CultureId == _cultureId
select new Genre
{
GenreId = t0.GenreId,
GenreName = t1.GenreName
};
return results.ToList();
}
}
I have tried different ways that I have found on the net.. but can't make it work!
Question 2:
I saw a screencast with Julie something, saying that "You should always return an ICollection" when using EF4.
Any thoughts about that ?
BR
EDIT:
When I load the page in Debug-mode i get these errors: The ObjectContext instance has been disposed and can no longer be used for operations that require a connection. OR The entity or complex type 'XModel.Genre' cannot be constructed in a LINQ to Entities query.
Genre must not be a L2EF type. Try this:
public IEnumerable<Genre> GetGenresByGame(int gameId)
{
using(var ctx = new XContext())
{
var resultList =
from t0 in ctx.GameGenres
join t1 in ctx.GenreCultureDetails on t0.GenreId equals t1.GenreId
where t0.GameId == gameId && t1.CultureId == _cultureId
select new { t0.GenreId, t1.GenreName };
var genres = resultList.AsEnumerable().Select(o => new Genre
{
GenreId = o.GenreId,
GenreName = o.GenreName
});
return genres.ToList();
}
}
First an foremost if Genre is in the database you should select it? If you have FKs from Genre->GenreCultureDetails let me know and I can update the below, but from the looks of it you could do it like this:
using(var ctx = new XContext())
{
var results =
from g in ctx.Genre
join gcd in ctx.GenreCultureDetails on g.GenreId equals gcd.GenreId
where g.GameId == gameId && gcd.CultureId == _cultureId
select g;
return result.ToList();
}
Alternatively continue down your path select them into an annoynmous type, and then copy them. You can use select instead of convertall if you please.
IList<Genre> returnMe = Null;
using(var ctx = new XContext())
{
var results =
from t0 in ctx.GameGenres
join t1 in ctx.GenreCultureDetails on t0.GenreId equals t1.GenreId
where t0.GameId == gameId && t1.CultureId == _cultureId
select new
{
GenreId = t0.GenreId,
GenreName = t1.GenreName
};
returnMe = results.ToList().ConvertAll(x=>new Genre(){
GenreId = x.GenreId,
GenreName = x.GenreName
}
);
}
return returnMe;

save new or update exist record with linq

this is the way i used to save record with linq: (my Q is below)
public void SaveEmployee(Employee employee)
{
using (BizNetDB db = new BizNetDB())
{
BizNet.SqlRep.Data.Employee oldEmployee = (from e in db.Employees
where e.EmployeeID == employee.EmployeeID
select e).SingleOrDefault();
if (oldEmployee == null)
{
oldEmployee = new BizNet.SqlRep.Data.Employee();
oldEmployee.BirthDate = employee.BirthDate;
oldEmployee.WorkRole = employee.WorkRole;
oldEmployee.CurrentFlag = employee.CurrentFlag;
oldEmployee.HireDate = employee.HireDate;
...
db.Employees.InsertOnSubmit(oldEmployee);
}
else
{
if (oldEmployee.BirthDate.Date != employee.BirthDate.Date)
oldEmployee.BirthDate = employee.BirthDate;
if (oldEmployee.CurrentFlag != employee.CurrentFlag)
oldEmployee.CurrentFlag = employee.CurrentFlag;
if (oldEmployee.HireDate.Date != employee.HireDate.Date)
oldEmployee.HireDate = employee.HireDate;
}
oldEmployee.ModifiedDate = DateTime.Now;
db.SubmitChanges();
employee.EmployeeID = oldEmployee.EmployeeID;
}
}
my questions are:
a. are the if statements nesccery? why not to make the assigning without the
check?
mybe the if block take more cpu..
b. why to spearate the new record block and the update block?
when the record is new it will do
db.Employees.InsertOnSubmit(oldEmployee);
and then proceed with the update routine...
The way you're doing it the only reason you need the if statement is to new it up and insert it, so I would use the if statement just for that.
I would do this instead:
public void SaveEmployee(Employee employee)
{
using (BizNetDB db = new BizNetDB())
{
BizNet.SqlRep.Data.Employee oldEmployee =
(from e in db.Employees
where e.EmployeeID == employee.EmployeeID
select e).SingleOrDefault();
if (oldEmployee == null)
{
oldEmployee = new BizNet.SqlRep.Data.Employee();
db.Employees.InsertOnSubmit(oldEmployee);
}
if (oldEmployee.BirthDate.Date != employee.BirthDate.Date)
oldEmployee.BirthDate = employee.BirthDate;
if (oldEmployee.CurrentFlag != employee.CurrentFlag)
oldEmployee.CurrentFlag = employee.CurrentFlag;
if (oldEmployee.HireDate.Date != employee.HireDate.Date)
oldEmployee.HireDate = employee.HireDate;
oldEmployee.ModifiedDate = DateTime.Now;
db.SubmitChanges();
employee.EmployeeID = oldEmployee.EmployeeID;
}
}
I also think there's a way to map one object's properties to the other, but it escapes me at the moment. It may not work for what you're trying to do anyway since it seems that you're doing some other things later anyway with the ModifiedDate and EmployeeID.

Resources