Linq is not updating my data...

  • Thread starter Thread starter Ilyas
  • Start date Start date
I

Ilyas

Hi all

I have the folowing code:

NorthwindDataContext nw1 = new NorthwindDataContext();

Category c1 = new Category();
c1.CategoryID = 1;
c1.CategoryName = "New Category2";
nw1.SubmitChanges();

//Note that the category name is
Category c2 = (from c in nw1.Categories where
c.CategoryID==1 select c).Single();
Assert.AreEqual(c1.CategoryName , c2.CategoryName);

This last line is not true meaning that the value of the Category
hasnt been updated? Why is this? Wha do I need to do to get this to
work as I would expect?

Many thanks
 
Ilyas said:
I have the folowing code:

NorthwindDataContext nw1 = new NorthwindDataContext();

Category c1 = new Category();
c1.CategoryID = 1;
c1.CategoryName = "New Category2";
nw1.SubmitChanges();

You haven't attached that to your data context. It's just a completely
free-floating object. If you want to insert a new entry, you need to
call nw1.Categories.InsertOnSubmit(c1)

If you want to update an existing entry, you should probably fetch it
first, then update it, then submit the change.
 
You haven't attached that to your data context. It's just a completely
free-floating object. If you want to insert a new entry, you need to
call nw1.Categories.InsertOnSubmit(c1)

If you want to update an existing entry, you should probably fetch it
first, then update it, then submit the change.

sorry I missed out a line - what I meant to say was :

NorthwindDataContext nw1 = new NorthwindDataContext();

Category c1 = new Category();
c1.CategoryID = 1;
c1.CategoryName = "New Category2";
nw1.SubmitChanges();

Category c2 = (from c in nw1.Categories where
c.CategoryID==1 select c).Single();
Assert.AreEqual(c1.CategoryName, c2.CategoryName); //This
line is false

Why is this - surly this should work right?
 
sorry I missed out a line - what I meant to say was :

             NorthwindDataContext nw1 = new NorthwindDataContext();

             Category c1 = new Category();
             c1.CategoryID = 1;
             c1.CategoryName = "New Category2";
             nw1.SubmitChanges();

            Category c2 = (from c in nw1.Categories where
c.CategoryID==1 select c).Single();
            Assert.AreEqual(c1.CategoryName, c2.CategoryName);//This
line is false

Why is this - surly this should work right?- Hide quoted text -

- Show quoted text -

Category c1 = new Category();
c1.CategoryID = 1;
c1.CategoryName = "New Category2";
nw1.Categories.InsertOnSubmit(c1);
nw1.SubmitChanges();

Category c2 = (from c in nw1.Categories where
c.CategoryID==1 select c).Single();
Assert.AreEqual(c1.CategoryName, c2.CategoryName);

The categoryName is not updated - why?
 
Ilyas said:
sorry I missed out a line - what I meant to say was :

NorthwindDataContext nw1 = new NorthwindDataContext();

Category c1 = new Category();
c1.CategoryID = 1;
c1.CategoryName = "New Category2";
nw1.SubmitChanges();

Category c2 = (from c in nw1.Categories where
c.CategoryID==1 select c).Single();
Assert.AreEqual(c1.CategoryName, c2.CategoryName); //This
line is false

That's exactly what you posted before. Where's the extra line?
Why is this - surly this should work right?

No - your original SubmitChanges() isn't doing anything, because you're
not adding anything to it.
 
Category c1 = new Category();
c1.CategoryID = 1;
c1.CategoryName = "New Category2";
nw1.Categories.InsertOnSubmit(c1);
nw1.SubmitChanges();

Category c2 = (from c in nw1.Categories where
c.CategoryID==1 select c).Single();
Assert.AreEqual(c1.CategoryName, c2.CategoryName);

Right, that's more like it. Is this your *actual* code, or do you have
more code around there?
The categoryName is not updated - why?

Well, you've told it to insert, not to update. Is there already a
Category with ID 1 before you run this code? Does it run without any
exceptions?
 
Right, that's more like it. Is this your *actual* code, or do you have
more code around there?


Well, you've told it to insert, not to update. Is there already a
Category with ID 1 before you run this code? Does it run without any
exceptions?


I do apologise for the confusion.
Im still confused. What im trying to do is to update an object without
getting linq to fetch it first

//Get the category t update
Category c1 = new Category();
c1.CategoryID = 1;

//Attach the object
nw1.Categories.Attach(c1);

//Now update the category
c1.CategoryName = "New Category2";

//save changes
nw1.SubmitChanges();

This gives me the error ChangeConflictException "Row not found or
changed" - my issue is that im not sure why this happens?
 
Ilyas said:
I do apologise for the confusion.
Im still confused. What im trying to do is to update an object without
getting linq to fetch it first

Hmm... not sure about that.
//Get the category t update
Category c1 = new Category();
c1.CategoryID = 1;

//Attach the object
nw1.Categories.Attach(c1);

//Now update the category
c1.CategoryName = "New Category2";

//save changes
nw1.SubmitChanges();

This gives me the error ChangeConflictException "Row not found or
changed" - my issue is that im not sure why this happens?

I suspect it's due to how you've got change tracking configured. As
ever, set the log to write the SQL out where you can see it - that's
likely to give hints as to what's going on.
 
Without a timestamp column it issues a WHERE matching all the old values -
i.e. (from a simple PUBS example):

UPDATE [dbo].[Employees]
SET [Extension] = @p16
WHERE ([EmployeeID] = @p0) AND ([LastName] = @p1) AND ([FirstName] = @p2)
AND ([
Title] = @p3) AND ([TitleOfCourtesy] = @p4) AND ([BirthDate] = @p5) AND
([HireDa
te] = @p6) AND ([Address] = @p7) AND ([City] = @p8) AND ([Region] = @p9) AND
([P
ostalCode] = @p10) AND ([Country] = @p11) AND ([HomePhone] = @p12) AND
([Extensi
on] = @p13) AND ([ReportsTo] = @p14) AND ([PhotoPath] = @p15)

Without the necessary data, it somehow short-circuits to "0=1". I haven't
checked how it detects this.

I think you will struggle to UPDATE an object that you didn't get via LINQ.
You can probably do it if you try hard enough... but... why? Note that you
can serialize/deserialize to round-trip:

Employee emp1;
using (PubsDataContext ctx = new PubsDataContext())
{
ctx.Log = Console.Out;
Employee emp0 = ctx.Employees
.Where(x => x.EmployeeID == 1).Single();
// make a seraialized clone
DataContractSerializer dcs = new
DataContractSerializer(typeof(Employee));
using(MemoryStream ms = new MemoryStream()) {
dcs.WriteObject(ms, emp0);
ms.Position = 0;
emp1 = (Employee) dcs.ReadObject(ms);
}
}
using (PubsDataContext ctx = new PubsDataContext())
{
ctx.Log = Console.Out;
ctx.Employees.Attach(emp1);
emp1.Extension = "2314";
ctx.SubmitChanges();
}
 
Without a timestamp column it issues a WHERE matching all the old values -
i.e. (from a simple PUBS example):

UPDATE [dbo].[Employees]
SET [Extension] = @p16
WHERE ([EmployeeID] = @p0) AND ([LastName] = @p1) AND ([FirstName] =@p2)
AND ([
Title] = @p3) AND ([TitleOfCourtesy] = @p4) AND ([BirthDate] = @p5) AND
([HireDa
te] = @p6) AND ([Address] = @p7) AND ([City] = @p8) AND ([Region] = @p9) AND
([P
ostalCode] = @p10) AND ([Country] = @p11) AND ([HomePhone] = @p12) AND
([Extensi
on] = @p13) AND ([ReportsTo] = @p14) AND ([PhotoPath] = @p15)

Without the necessary data, it somehow short-circuits to "0=1". I haven't
checked how it detects this.

I think you will struggle to UPDATE an object that you didn't get via LINQ..
You can probably do it if you try hard enough... but... why? Note that you
can serialize/deserialize to round-trip:

       Employee emp1;
        using (PubsDataContext ctx = new PubsDataContext())
        {
            ctx.Log = Console.Out;
            Employee emp0 = ctx.Employees
                .Where(x => x.EmployeeID == 1).Single();
            // make a seraialized clone
            DataContractSerializer dcs = new
DataContractSerializer(typeof(Employee));
            using(MemoryStream ms = new MemoryStream()) {
                dcs.WriteObject(ms, emp0);
                ms.Position = 0;
                emp1 = (Employee) dcs.ReadObject(ms);
            }
        }
        using (PubsDataContext ctx = new PubsDataContext())
        {
            ctx.Log = Console.Out;
            ctx.Employees.Attach(emp1);
            emp1.Extension = "2314";
            ctx.SubmitChanges();
        }

This doesnt make any sense to me. In effect what you are saying is
that I need to fetch the objec from linq first, make the changes and
then update it

My question is why do I need to get it from Linq first?

I've noticed that the update command issued is
exec sp_executesql N'UPDATE [dbo].[Categories]
SET [CategoryName] = @p0
WHERE 0 = 1',N'@p0 nvarchar(13)',@p0=N'New Category2'

..which of course wont actually update any rows. Interesting enough
theres no mention of my CategoryId...
 
This doesnt make any sense to me. In effect what you are saying is
that I need to fetch the objec from linq first, make the changes and
then update it

Or change the change-tracking method your entity uses.
My question is why do I need to get it from Linq first?

LINQ is trying to make sure you're not overwriting someone else's
changes accidentally.
I've noticed that the update command issued is
exec sp_executesql N'UPDATE [dbo].[Categories]
SET [CategoryName] = @p0
WHERE 0 = 1',N'@p0 nvarchar(13)',@p0=N'New Category2'

..which of course wont actually update any rows. Interesting enough
theres no mention of my CategoryId...

That's exactly what Mark said:

<quote>
Without the necessary data, it somehow short-circuits to "0=1". I
haven't checked how it detects this.
</quote>
 
Back
Top