Updating a column using LINQ - c#

My table has two ID fields (I did not put 2 IDs so dont ask me why). One is a primary key and the other is a nullable duplicate field which will contain the value of the primary key itself.
public static void UpdateDuplicate_ID(Company updatingCompany)
{
Company tempCompany;
using (var context = new TestLiveDataContext())
{
tempCompany = (from company in context.Companies
where company.Id == updatingCompany.Id
select company).FirstOrDefault();
tempCompany.DuplicateId = updatingCompany.DuplicateId;
context.SubmitChanges();
}
}
It seems the above code is not working. I can't update the duplicate id with my primary key value. Can anyone tell me whether I am missing anything here?

As much as I can see, updatingCompany and tempCompany appear to be the same record.
If this is the case, you may be overwriting the chance outside of this method if you later change the value passed in and save again.
Does beg the question, why don't you just change the value in updatingCompany and then submit changes on its own context, rather than starting up a new one?
That is unless I have misunderstood the problem.

Related

MVC comparing changes to existing values

I've currently got a bit of an issue when trying to check values that have been posted as part of an update, to what is currently being held in the database.
Currently what i'm doing is reading the existing record into a new variable, alongside the one passed in from the post, and checking values in that variable. However I've just noticed that as soon as I read the record from the database, the values passed in from the post get reset to their previous value.
I have a feeling that the reason is that the posted record and the retrieved record both have the same primary key value, and so the code is then overwriting the new values as there can't be two different objects with the same primary key in memory. Though that is just a guess.
Can someone help me with this issue, and possibly help me find a way to get around this?
EDIT:
My code is below. This is the main code, and as soon as I retrieve the "original record", the values in the "faultrecord" get reverted to what they were before
[HttpPost]
public ActionResult Edit(fault faultrecord)
{
fault originalRecord = _faultRepository.Read(faultrecord.ID); /*here is where it gets reverted*/
if (faultrecord != originalRecord)
{
/*perform actions and update record*/
}
}
The below code is what I use to read the record from the database:
public fault Read(int id)
{
var result = ITJobEntities.faults.Where(t => t.ID == id);
if (result.Any())
{
return result.FirstOrDefault();
}
return null;
}
My only reason for believing it to be to do with the primary keys is because when I added in the "originalRecord" retrieval, my update statement to the database started failing due to there being multiple objects with the same ID (the actual error was a bit more descriptive, but I can't remember it fully).

How to set a property value to auto increment in visual studio lightswitch 2012

i want to set a property value in a table to default auto increment,but their are no options to do so in lightswitch2012 to my knowledge which is given that i recently started learning lightswitch,very light.
ok heres the real problem,this is the table
[customer][id,customer_id,name]
i want to set customer_id by default to id unless it is manually changed to different value.
how to acheive this?
In the Entity designer make your Customer_ID not required.
Write Code for Customers_Inserted.
Then, check to see if the Customer_ID is null. If it is, copy the ID field to it.
private void Customers_Inserted(Customer entity)
{
if (entity.Customer_ID == null) {
entity.Customer_ID = entity.ID;
}
}
You're right, there is no "auto-increment" data type available in LightSwitch. The ID property auto-increments, but that's a special case, handled by LightSwitch.
If you were attaching to an external SQL database, if you added a column that was an Integer Identity column, although it'll just appear as an Integer property in LightSwitch, it would still auto-increment because that's actually done in the SQL database itself.
The problem with all auto-increment properties is that you won't get the actual value until the record is saved.
Can I ask why you need an auto-increment property?
I may be misunderstanding what you are trying to achieve, but if you are using either a table or a grid, and you want to set the values for various entities for each new row your user adds (like customer_id = id, etc.), you can use the _Changed method and Add event to programmatically set any of the new row entities.
If this is along the lines of what you're looking for, watch Beth Massi's video How Do I: Copy Data from One Row into a New Row? You should be able to adapt her code to accomplish what you have in mind I think.

"Predict" next model ID

Sheesh...
I think this can be done but I just can't figure it out at the moment.
So I've created this app, that's working fine. But for some reason (too long to explain sorry) I would need to predict next ID to come from data table.
Note that last id + 1 will not work. I've tried this.
var lastProperty = db.Properties.OrderByDescending(p => p.PropertyID).FirstOrDefault();
int propID;
if (lastProperty == null)
{
propID = 1;
}
else
{
propID = 1 + lastProperty.PropertyID;
}
And as long as properties don't get deleted it works...
As soon as one is deleted, it messes up of course, since lets say we delete 6th Property,
last one will be 5th now, and with that code we'll get 6 5(last one) + 1, and I save my model related to Property with PropertyID 6 which I got from that code, and next Property will be 7 since database still remembers that 6 existed and was deleted... Model I intended to have same PropertyID as THAT last Property will not have it, and it'll fail...
Also, I can't add this AFTER saving Property, I realize that might seem as a solution but it's not. It has to be predicted.
Thank you... Please help...
UPDATE
This is the use case I'm trying to accomplish.
Property model with ID Name DataType properties.
List model with ID ListValue PropertyID properties.
When new Property is created user types in the Name, and from premade dropdown list for DataType selects a value, if that value is List, it opens additional form that contains a listbox, textbox and a button (add_Button). User types in the value in a textbox, and clicks the add_Button to add it to List.
Listbox is populated from List model, and add_Button, saves values from textbox to ListValue property of List, also as you've seen, I'm trying to manually add PropertyID to List by predicting it's value...
Then, upon finishing adding all the elements wanted through textbox, by clicking Create button, Property is then saved.
Hope this was clear enough.
It seems like you want to know the current state of the identity column:
SELECT IDENT_CURRENT('Table')
When need to know what your primary key values are going to be before committing to the Db you could use a uniqueidentifier (GUID) as the Pk for your Property and therefore as the Fk for your List entity. That way you can create it your self and it'll always be unique on committal.
You mention Entity Framework, have you tried adjusting your model?
StoreGeneratedPattern can be adjusted to allow automatic update of your local model when you store to the database.

Duplicate record created, but why? (linq to sql)

We got a table that stores newsletter subscriptions (ID, EmailAddress, MyNewsletter1 etc), and when we save a subscription we first check to see if there already is a subscription set up for that email address. If there is, we update that record, if there isn't we insert a new one. Somehow a duplicate email address has sneaked its way in there, and I'm not sure how. The primary key is ID, so we can change that to be EmailAddress instead, but I'm still curious how this happened. Could it be a concurrency issue? This is the code:
public static void SaveSubscription(NewsletterSubscription subscription)
{
using (MyDataContext db = new MyDataContext())
{
// does this email already have subscriptions?
NewsletterSubscription result = db.NewsletterSubscriptions.SingleOrDefault(r => r.Email == subscription.Email);
if (result != null)
{
// update instead of creating new record
result.MyNewsletter1 = subscription.MyNewsletter1;
result.MyNewsletter2 = subscription.MyNewsletter2;
result.MyNewsletter3 = subscription.MyNewsletter3;
result.MyNewsletter4 = subscription.MyNewsletter4;
}
else
{
// create new subscription record
subscription.RegisterDate = DateTime.Now;
db.NewsletterSubscriptions.InsertOnSubmit(subscription);
}
db.SubmitChanges();
}
}
Thanks,
Annelie
It sounds like this is simply a race condition between two connections doing the read/insert. One fix might be to create a serializable transaction around the two operations:
using (var tran = new TransactionScope()) {
using (MyDataContext db = new MyDataContext()) {
// ... your existing code here
}
tran.Complete();
}
This forces a key-range lock during the select, so any second thread doing the read will be blocked until the transaction has completed; so you won't get two SPIDs seeing "no row" then trying to do the insert; instead the first SPID will block the second for a few critical milliseconds while it does the work; only when the first SPID has decided whether (or not) to insert the data (and call Complete or rollback) does the second SPID get to know.
Also, note that you don't need to change the primary key to make it unique - just add a unique constraint. Then you don't have to change anything referencing that table.
As some have already stated this is probably a concurrency issue and you should let the database help you avoid it. If you don't want to change the primary key then you could add a unique constraint to your email column.
The code seems ok, so I would guess a concurrency issue. If the e-mail should only have one record anyway, I would suggest adding/replacing that on the primary key.
In that case SubmitChanges will throw an exception if you try to insert the same record again. Then you can take measured inside the catch block to update the record (or discard it if that is proper), and continue execution.
Get the database to help you avoid duplicated by providing proper primary keys.

MVC 2 Unique index validation

Is there a way to validate a property that should be unique on a model? For example, a user can create and edit a "Product", but they shouldn't be able to create a Product with an existing ProductCode, nor should they be able to edit a Product and change the ProductCode to a code that already exists.
I have tried using a custom attribute.
public class Unique : ValidationAttribute
{
public override bool IsValid(object value)
{
var products = Repository.Store.Products.Where(x => x.ProductCode == value);
return (products.Count() == 0);
}
}
All that I can cover with this solution is not allowing the user to insert/update a Product when the code already exists in the DB. This does not allow the user to edit an existing product because when they submit, it will see that the code already exists(it will be the code for the product they are trying to edit.) and returns false.
Is there no way of dealing with a unique index in MVC 2, I have searched for hours, even found other topics on stackoverflow, but nothing with a solid solution.
Just let the insert or update fail and then return an appropriate error message to the user. Checking up front is problematic anyway since there's always a chance that another user will modify the database immediately after your check.
Here's an example of how you can insert an object and determine whether or not it failed due to a unique constraint:
INSERT INTO MyTable (column1, column2, column3)
SELECT #param1, #param2, #param3
WHERE NOT EXISTS (SELECT * FROM table WHERE id = #param4)
If the object already exists, this will modify 0 rows. If it does not, then it will modify 1 row. If anything else goes wrong, you'll get an exception. This is also quite efficient (at least in SQL server). It results in an index seek followed by an index update, just as you would hope.
I struggled with MVC a little in a related area.
Part of the answer gleaned to my question was that you should "probably" have a seperate model for Insert and Update of an object.
That way you could have your custom attribute just on the insert model.
Otherwise, just take care of this as a normal code check in your insert method, not in a custom attribute.
Ok I see....
Can you do a "does not equal" check on the exists for some unique ID on the object - that way you check for the existence of the product code BUT not on the current product.

Categories