LINQ To SQL Not Submitting Changes - c#

This seems like a popular question as I've seen several threads on this. However, I can't get updates to work. I have some LINQ-to-SQL code that looks like the following:
int orderID = GetOrderID();
using (DBDataContext database = new DBDataContext())
{
var order = database.Orders.FirstOrDefault(x => x.OrderID == orderID);
if (order != null)
{
order.IsOpen = GetIsOpen();
database.SubmitChanges();
}
}
I can set my breakpoint and see that it is getting into my IF statement. I've also fired up SQL profiler and have noticed that no statements are coming in for this code. Yet, I can successfully add Orders using the following code:
Order newOrder = GetNewOrder();
using (DBDataContext database = new DBDataContext())
{
database.Orders.InsertOnSubmit(newOrder);
database.SubmitChanges();
}
What am I doing wrong?

I think you may need to mark the Order as changed by doing the following
database.MarkAsModified(order)
before database.SubmitChanges()

Related

Insert into multiple tables using WCF Transactions

I am trying to add an entry into a table and use the primary key of that added entry to create an additional entry into another table.
The error I am getting is
The transaction manager has disabled its support for remote/network
transactions. (Exception from HRESULT: 0x8004D024)
I believe this is caused by creating multiple connections within a single TransactionScope, but I am doing everything within one context / using statement, so I do not believe that I should be receiving this error.
Service
[OperationBehavior(TransactionScopeRequired = true)]
public void CreateGroup(NewGroupData data)
{
var groupRepo = _GroupRepo ?? new InvestigatorGroupRepository();
groupRepo.CreateGroup(data.UserId, data.InvestigatorGroupName, data.HasGameAssignment, data.InstitutionId);
}
Repository
public void CreateGroup(string userId, string investigatorGroupName, bool hasGameAssignment, int institutionId)
{
using (var context = new GameDbContext())
{
var newGroup = new InvestigatorGroup()
{
InvestigatorGroupName = investigatorGroupName,
HasGameAssignment = hasGameAssignment,
InstitutionId = institutionId,
IsTrashed = false
};
int institutionUserId =
context.InstitutionUsers.Where(
iu => !iu.IsTrashed && iu.APUser.UserId == userId && iu.InstitutionId == institutionId).Select(iu => iu.InstitutionUserId).Single();
var newGroupUser = new InvestigatorGroupUser()
{
InstitutionUserId = institutionUserId,
InvestigatorGroup = newGroup,
CreationDate = DateTime.Now
};
context.InvestigatorGroupUsers.Add(newGroupUser);
context.SaveChanges();
}
}
You start with a wrong assumption.
The line...
int newGroupId = context.InvestigatorGroups.Add(newGroup).InvestigatorGroupId;
...will always assign 0 to newGroupId. The Add method only marks the entity for insert, but doesn't actually insert it. Only SaveChanges writes data to the database, not any other method in Entity Framework.
So the assignment...
InvestigatorGroupId = newGroupId,
...is faulty as well. You have to assign the new InvestigatorGroup to a navigation property in InvestigatorGroupUser:
InvestigatorGroup = newGroup,
Add this navigation property to InvestigatorGroupUser if you haven't got it yet.
If you have that, it's enough to execute these lines:
context.InvestigatorGroupUsers.Add(newGroupUser);
context.SaveChanges();
No need to Add the newGroup object too, It will be added by adding newGroupUser.
So if you do that, the only transaction you need is the one that SaveChanges uses internally by default. For the code you show, you don't need a TransactionScope. If this is part of a greater WCF transaction the story may be different, but I think at least you needed some misconceptions to be straightened out.

Update all unique records (compare a field in 2 different tables)

I hope you can help me.
I would like to update all Unique records by verifying that the Project Number of one table does not exist in the other.
Currently I have the procedure below, but I get an error as the returned results are more than 2100:
The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect. Too many parameters were provided in this RPC request. The maximum is 2100.
I have done a lot of reading and research on this issue, but am struggling to find and implement a simple solution that will work for my purposes. Please note: I am a newbie.
Any ideas how I can rewrite this to work?
public static void NewRecords()
{
using (var stageContext = new StagingTableDataContext())
{
using (var destinationContext = new DestinationTableDataContext())
{
var allProjectNames = destinationContext.THEOPTIONs.Select(u => u.NAME).ToList();
var deltaList = stageContext.ProjectMasters.Where(u => !allProjectNames.Contains(u.Finance_Project_Number)).ToList();
deltaList.ForEach(u => u.Processing_Result = 0);
deltaList.ForEach(u => u.Processing_Result_Text = "UNIQUE");
}
stageContext.SubmitChanges();
}
}
Thank you in advance!
You're getting the error message because allProjectNames hold too many records to be parameterized for the second select statement. You could either fetch the entire ProjectMasters table first (see below my extra added ToList), and then query it. Or implement a stored procedure which takes a table parameter.
public static void NewRecords()
{
using (var stageContext = new StagingTableDataContext())
{
using (var destinationContext = new DestinationTableDataContext())
{
var allProjectNames = destinationContext.THEOPTIONs.Select(u => u.NAME).ToList();
var deltaList = stageContext.ProjectMasters.ToList().Where(u => !allProjectNames.Contains(u.Finance_Project_Number)).ToList();
deltaList.ForEach(u => u.Processing_Result = 0);
deltaList.ForEach(u => u.Processing_Result_Text = "UNIQUE");
}
stageContext.SubmitChanges();
}
}

Linq to SQL fetching cached results

when I select objects using Linq, i seem to get cached results at first.
I use the following code to fetch an applicant from the DB on GET requests assume that this data is STATE_1
using (AdmissionsAppEntities db = new AdmissionsAppEntities())
{
// Fetch the user
ApplicationData applicant = (from a in db.ApplicationDatas
where a.userGUID == userGUID
select a).SingleOrDefault();
}
and the following code to save changes against this record on POST requests, after the SaveChanges is called this record should be in STATE_2
using (AdmissionsAppEntities db = new AdmissionsAppEntities())
{
// Fetch the user
var applicant = (from a in db.ApplicationDatas
where a.userGUID == userGUID
select a).SingleOrDefault();
if (applicant != null)
{
// Save page 1 data
...
applicant.lastUpdate = DateTime.Now;
db.Entry(applicant).State = EntityState.Modified;
DataBag.result = db.Entry(applicant).GetValidationResult();
if (DataBag.result.ValidationErrors.Count == 0)
{
db.SaveChanges();
}
}
}
if (DataBag.result.ValidationErrors.Count == 0)
{
return RedirectToAction("PageTwo");
}
The database properly saves STATE_2 (i can see it in the db if I use a sql inspection tool), but on subsequent pageload, STATE_1 is retrieved.
I see tons of results where people are having this issue, but no ideas on how to fix it.
UPDATE 1
I moved the RedirectToAction calls (all my returns) to outside the using block to make sure that each DbContext's Destroy function gets called. Did not appear to solve the problem.
People are actually having this issue, so I'm going to leave this up, my issue ended up being Orchard CMS caching my module's pages.

Failing to write to database using entity framework ( edmx )

As the title says, I have a problem writing to local database. I generated a edmx Model from this, and I can easily read from it.
EDMXNS.TOWDataBasev1Entities db = new EDMXNS.TOWDataBasev1Entities();
var query = from p in db.Accounts select p;
foreach (EDMXNS.Accounts s in query)
Console.WriteLine(s.AccountName);
That works fine. However when I try to write to the database, nothing happens. I do not get any errors, exceptions etc. I figure, since I can read from the database, that it's not a connection problem.
Here is the code i have for writing.
EDMXNS.TOWDataBasev1Entities db = new EDMXNS.TOWDataBasev1Entities();
EDMXNS.Accounts acc = new EDMXNS.Accounts();
acc.AccountID = 1;
acc.AccountName = "testuser";
acc.AccountPW = "testpw";
acc.PersonDataID = 0;
db.AddToAccounts(acc);
db.SaveChanges();
It is worthwhile to meantion that my Accounts.AccountID has identity/autoincrement, but I have tried both setting it to the next known value, or simply not setting it at all.
Do anyone have an idea as to what might cause this problem?
EDIT: I also tried to remove the custom name space, delete all records of the database and reimport it all.
Removing the custom tool name space, results in errors like these:
Ambiguity between 'TOWServer.Accounts.AccountName' and 'TOWServer.Accounts.AccountName'
Which doesnt tell me anything.
Reimporting everything now gives me an exception:
"Unable to load the specified metadata resource"
I've always use this format when adding records with EF, Try following this format:
using (MovieStoreEntities context = new MoveStoreEntities())
{
try
{
context.Movies.AddObject(new Movie() { MovieID = 234,
Title = "Sleepless Nights in Seattle", Quantity = 10 });
context.SaveChanges();
}
catch(Exception ex)
{
Console.WriteLine(ex.InnerException.Message);
}
}

Cant update table from text using linq2sql

Using linq2sql I'm trying to take the string in txtOilChange and update the oilChange integer in the car table of the white fusion.
I know my code below is wrong but what do I need to change?
using (DataClasses1DataContext db = new DataClasses1DataContext())
{
var o = (from c in db.cars
where c.carDesc == "White Fusion"
select c).First();
txtOilChange.Text = o.oilChange.ToString();
db.SubmitChanges();
}
If you're trying to update the record it looks like the assignment statement is reversed.
This:
txtOilChange.Text = o.oilChange.ToString();
Should be:
o.oilChange = int.Parse(txtOilChange.Text);
For better error handling consider using the TryParse method:
int oilChangeValue;
if (int.TryParse(txtOilChange.Text, out oilChangeValue))
{
o.oilChange = oilChangeValue;
db.SubmitChanges();
}
else
{
// invalid value
}

Categories

Resources