How to update a single field using EF4 - entity-framework-4

I want to update a single field in my table for a particular row. I am using Entity Framework 4 and Visual Studio 2010.
Options I can think of are:
Using a Stored Procedure
Direct connection to the database and using
sql statement
I am not aware of any more efficient method to perform this task.
[EDIT]
I would like to do the update in the same operation as the Get for that row, so that it is done in one DB call.

No need to complicate things. Just change the one property and SaveChanges. Unless you're doing something odd, that should only change the one column. Look at the SQL to verify.

Related

How do I add data to a database in Delphi by using edits instead of a DBNavigator?

My interface is very basic. It just includes edits for the user to input data into a database, when they click the button i want it to add the data into my database.
You can easily do this.
Go to the Data Controls tab of the Component palette.
Select a TDBEdit and place it on the same form as your DBNavigator. The IDE will name this DBEdit1
Set the Datasource property of your DBEdit1 to the same datasource as your DBNavigator.
Set the DataField property of DBEdit1 to the name of a field in your dataset.
Compile and run.
That's it. Leave your DBNavigator on your form because you will find that when you make a change to the contents of DBEdit1, its Save and Cancel buttons automatically enable to let you save or cancel the change.
Also, you'll find that if you click your DBNavigator's '+' button, which begins the insertion of a new record into your table, you can then type the field values for the new record into your DBEdits.
Don't use normal non-DB-aware TEdit components and a dynamically-created Sql statement which concatenates the TEdits's contents with other Sql as suggested in the other answer which briefly appeared here and now seems to have been deleted - it is a waste of time, but much more importantly renders your app vulnerable to Sql-Injection - see https://en.wikipedia.org/wiki/SQL_injection. By sending the server an unverified Sql statement which includes what the user has typed into a TEdit, you're effectively providing the user with an opportunity to type additional Sql statements into the TEdit and that is exactly how Sql injection can occur. On the other hand, when you use TDBEdits, the Sql for updating the database record is automatically generated by Delphi's TDataSet framework in a way which does not provide a similar opportunity for Sql Injection.
If some reason you absolutely have to generate your own Sql Update statements, to minimise the risk of Sql Injection, make sure that you use a parameterised Update statement, that is, one where the changed field values are specified as values of parameters in your TDataSet-descendant's Parameters object, rather than in the Update Sql itself. An example of a parameterised Update statement might be:
Update MyTable set FieldA =:FieldA, FieldB=:FieldB where RowID =:RowID
where :FieldA, :FieldB and :RowID are the parameters.

Auditing Changes under MVC & Entity Framework (using sprocs)

I have the challenge of needing to audit data changes made by users of an MVC application.
Auditing creation and deletion of records is easy.
Updates is proving to be the problem.
I'm looking for a way to automate this, but the problem I have is that the application is using stored procedures to bring back EF "complex types".
These are then used to build a view model, and after postback, the controller receives a new view model built from the form values passed back from the view. Therefore the original values are no longer available.
Does anyone have any suggestions for a secure way to keep the original values so they can be compared with the updated values, so that changes can be stored?
(I appreciate I could go back to the database for these, but is not efficient, and I would have to retain all the parameters to remake the same call, and find a way to automate that part of the process).
Have you tried an Audit Trigger using the INSERTED and DELETED tables.
http://weblogs.asp.net/jgalloway/archive/2008/01/27/adding-simple-trigger-based-auditing-to-your-sql-server-database.aspx
OR
In your stored procedures for insert,delete,update you can make use FOR XML AUTO. To get the XML for the record and add it to an audit table.
http://www.a2zdotnet.com/View.aspx?Id=71
UPDATE A T-SQL example
BEGIN
-- these tables would be in your database
DECLARE #table TABLE(ID INT IDENTITY(1,1) PRIMARY KEY, STR VARCHAR(10), DT DATETIME)
DECLARE #audit_table TABLE(AuditXML XML, Type VARCHAR(10), Time DATETIME)
-- this is defined at the top of your stored procedure
DECLARE #temp_table TABLE(PK INT)
-- your stored procedure will add an OUTPUT to the temp table
INSERT INTO #table
OUTPUT inserted.ID INTO #temp_table
VALUES ('test1', GetDate()),
('test2', GetDate() + 2)
-- at the end of your stored procedure update your audit table
INSERT INTO #audit_table
VALUES(
(
SELECT *
FROM #table
WHERE ID IN (SELECT PK FROM #temp_table)
FOR XML AUTO
),
'INSERTION',
GETDATE()
)
-- your audit table will have the record data
SELECT * FROM #audit_table
END
In the example above you could make temp_table a clone of table (have all of the columns from table) and in your OUTPUT clause use INSERTED.* INTO #temp_table, this would avoid have to reselect the records before getting the FOR XML AUTO. Another note, for stored procedures that do DELETE you would use DELETED.* instead of INSERTED.* in your OUTPUT.
If using SQL Server I recommend that you look into Change Data Capture (CDC).
It's an out of the box solution for auditing changes to the underlying tables of your application and it's relatively straightforward to set up, so there is no need for a custom solution that you then have to maintain.
If you have any supporting applications for your site, they'll also be covered and it also has the benefit of auditing any changes made directly against the database, such as from a DBA running a script.
Since your asp.net application may be running under one particular account, you'll probably need to add additional tracking information to capture the user who made the change. Fortunately this is also relatively straightforward. The following Stack Overflow question covers an approach to this using the ObjectStateManager
I was lookging for this myself, found this, check out Tracker for EF

linq: SQL performance on high loaded web applications

I started working with linq to SQL several weeks ago. I got really tired of working with SQL server directly through the SQL queries (sqldatareader, sqlcommand and all this good stuff). 
After hearing about linq to SQL and mvc I quickly moved all my projects to these technologies. I expected linq to SQL work slower but it suprisongly turned out to be pretty fast, primarily because I always forgot to close my connections when using datareaders. Now I don't have to worry about it.
But there's one problem that really bothers me. There's one page that's requested thousands of times a day. The system gets data in the beginning, works with it and updates it. Primarily the updates are ++ # -- (increase and decrease values). I used to do it like this
UPDATE table SET value=value+1 WHERE ID=#I'd
It worked with no problems obviously. But with linq to SQL the data is taken in the beginning, moved to the class, changed and then saved.
Stats.registeredusers++;
Db.submitchanges();
Let's say there were 100 000 users. Linq will say "let it be 100 001" instead of "let it be increased by 1".
But if there value of users has already been increased (that happens in my site all the time) then linq will be like oops, this value is already 100 001. Whatever I'll throw an exception"
You can change this behavior so that it won't throw an exception but it still will not set the value to 100 002.
Like I said, it happened with me all the time. The stas value was increased twice a second on average. I simply had to rewrite this chunk of code with classic ado net.
So my question is how can you solve the problem with linq
For these types of "write-only queries" I usually use a Stored Procedure. You can drag the stored procedure into the designer and execute it through the Linq to SQL DataContext class (it will be added as a method).
Sorry for the trite answer but it really is that simple; no need to to finagle with raw ADO.NET SqlCommand objects and the like, just import the SP and you're done. Or, if you want to go really ad-hoc, use the ExecuteCommand method, as in:
context.ExecuteCommand("UPDATE table SET value = value + 1 WHERE ID = {0}", id);
(But don't overuse this, it can get difficult to maintain since the logic is no longer contained in your DataContext instance. And before anybody jumps on this claiming it to be a SQL injection vulnerability, please note that ExecuteCommand/ExecuteQuery are smart methods that turn this into a parameterized statement/query.)
Linq to Sql supports "optimistic" concurrency out of the box. If you need tighter control, you can add a Timestamp column to your table, and Linq to Sql will use that timestamp to tighten the concurrency.
http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2008/07/01/10557.aspx
However, as Morten points out in the comments below, this solution is not going to perform well. Of course, you can always use ADO.NET to update the value, just like you were doing before; that won't adversely affect the operation of your Linq queries at all.
You could turn off concurrency on that property by changing the UpdateCheck value:
http://msdn.microsoft.com/en-us/library/bb399394(v=VS.90).aspx
Messy if your using generated code and the designer but I think this is the only way to do this.

How to make UPDATE queries in LINQ to SQL?

I like using LINQ to SQL. The only problem is that I don't like the default way of updating tables.
Let's say I have the following table with the following columns:
ID (primary key), value1, value2, value3, value4, value5
When I need to update something I call
UPDATE ... WHERE ID=#id
LINQ to SQL calls
UPDATE ... WHERE ID=#id and value1=#value1 and value2=#value2 and value3=#value3 and value4=#value4 and value5=#value5
I can override this behavior by adding
UpdateCheck=UpdateCheck.Never
to every column, but with every update of the DataContext class with the GUI, this will be erased. Is there any way to tell LINQ to use this way of updating data?
I'm confused by this statement:
but with every update of the DataContext class with the GUI, this will be erased. Is there any way to tell LINQ to use this way of updating data?
By "the GUI", do you mean the Linq to SQL designer? Because the property sheet for each member has an "Update Check" property that you can set to "Never". If you are manually editing the .designer.cs file, don't do that, instead change the Update Check setting in the actual designer.
Designer Screen http://img29.imageshack.us/img29/7912/updatecheckdesigner.png
Please note: The "default way" of updating used by Linq to SQL is called optimistic concurrency, and is a way of preventing conflicting updates from multiple users. If you turn this off by using the method above, you have to be prepared to deal with the fact that if two users have the same record open at the same time, the second user's changes will overwrite the first user's changes without any warning or confirmation. Be sure that this is the behaviour you really want.
Unfortunately, no, there's not. You have to edit the DBML manually after it is generated (or updated) - which is a pain (or use the Designer as already mentioned in the other answer).
When I last used L2S on a project, I wrote a quick utility which ran post-generation and fixed it up, but it's an unnecessary pain which (c)shouldn't be required IMHO.
Ran into this one myself. The trick is to change the way one generates the DBML--such as using l2st4. Then you can set that pesky UpdateCheck property to always be never by modifying the template.
That is how Linq works. Why don't you like this update behavior?
Read about optimistic concurrency
http://msdn.microsoft.com/en-us/library/bb399373.aspx

MVC using Linq to Entity w/ sql encryption

Currently i am using sql encryption and would like to continue using it through Linq. I have all my CRUD stored proc's wired up to the table in order to handle the encryption/decryption on the backend. Problem is my database model see's a field type of varbinary(max) which is used for the sql encryption storage. The retrieval sp for this table does the decryption thus returning a string value. How does one get around this. Seems like the model needs to recognize a string in place of the varbinary but i am unsure of how to handle this.
Thanks in advance.
So change the table mapping to a view mapping in the database model?
Off the top of my head, some choices:
Edit the ssdl manually.
Make a view and map that (you don't need to actually use it for anything but mapping).

Resources