ASP.NET MVC3 database manipulation - c#

Right now, I have a simple web application that displays the entries of a database. One of the fields that is visible in the database is a bool?, which is true, false, or neither. Everything in the database originally should have the bool? set to neither.
Here's what I want to get working: when a user edits an entry in the table by selecting either true or false for the bool? field, I want to be able to run some C# code (that I have already written) and have that entry deleted from the database. This means that the next time that the database is loaded, once again all the entries will have neither true nor false selected in the bool? field.
Does someone know how I can do this simply? (I know very little about querying databases or creating web apps in general.)

My problem was less about how to delete the items and more about how to pick out from the database those chosen to be deleted.
I found that this does the trick:
var toBeRemoved = from m in db.Issues
where m.Remove.HasValue && m.Remove
select m;

I believe when you say "true, false, or neither", the neither means null in the database, so, without seeing your code, I believe you could change the SELECT that retrieves the rows for the view to display, to have a WHERE *field* IS NULL in it. If this doesn't help, please post us some control, view, and model code.

Related

Remove list values based on series of other values

I have a situation wherein a List object is built off of values pulled from a MSSQL database. However, this particular table is mysteriously getting an errant record or two tossed in. Removing the records cause trouble even though they have no referential links to any other tables, and will still get recreated without any known user actions taken. This causes some trouble as it puts unwanted values on display that add a little bit of confusion. The specific issue is that this is a platform that allows users to run a search for quotes, and the filtering allows for sales rep selection. The select/dropdown field is showing these errant values, and they need to be removed.
Given that deleting the offending table rows does not provide a desirable result, I was thinking that maybe the best course of action was to modify the code where the List object is created and either filter the values out or remove them after the object is populated. I'd like to do this in a clean, scalible fashion by providing some kind of appendable data object where I could just add in a new string value if something else cropped up as opposed to doing something clunky that adds new code to find the value and remove it each time.
My thought was to create a string array, and somehow loop through that to remove bad List values, but I wasn't entirely certain that was the best way to approach this, and I could not for the life of me think of a clean approach for this. I would think that the best way would be to add a filter within the Find arguments, but I don't know how to add in an array or list that way. Otherwise I figured to loop through the values either before or after the sorting of the List and remove any matches that way, but I wasn't sure that was the best choice of actions.
I have attached the current code, and would appreciate any suggestions.
int licenseeID = Helper.GetLicenseeIdByLicenseeShortName(Membership.ApplicationName);
List<User> listUsers;
if (Roles.IsUserInRole("Admin"))
{
//get all users
listUsers = User.Find(x => x.LicenseeID == licenseeID).ToList();
}
else
{
//get only the current user
listUsers = User.Find(x => (x.LicenseeID == licenseeID && x.EmailAddress == Membership.GetUser().Email)).ToList();
}
listUsers.Sort((x, y) => string.Compare(x.FirstName, y.FirstName));
-- EDIT --
I neglected to mention that I did not develop this, I merely inherited its maintenance after the original developer(s) disappeared, and my coworker who was assigned to it left the company. I'm not really really skilled at handling ASP.NET sites. Many object sources are hidden and unavailable for edit, I assume due to them being defined in a DLL somewhere. So, for any of these objects that are sourced from database tables, altering the tables will not help, since I would not be able to get the new data anyway.
However, I did try to do the following to filter out the undersirable data:
List<String> exclude = new List<String>(new String[] { "value1" , "value2" });
listUsers = User.Find(x => x.LicenseeID == licenseeID && !exclude.Contains(x.FirstName)).ToList();
Unfortunately it only resulted in an error being displayed to the page.
-- EDIT #2 --
I got the server setup to accept a new event viewer source so I could write info to the Application log to see what was happening. Looks like this installation of ASP.NET does not accept "Contains" as an action on a List object. An error gets kicked out stating that the method is not available.
I will probably add a bit to the table and flag Errant rows and then skip them when I query the table, something like
&& !ErrantData
Other way, that requires a bit more upkeep but doesn't require db change, would be to keep a text file that gets periodically updated and you read it and remove users from list based on it.
The bigger issue is unknown rows creeping in your database. Changing user credentials and adding creation timestamps may help you narrow down the search scope.

Conditional mapping using GraphDiff

I am having an issue with GraphDiff whilst saving some data and I just need some one to confirm if this is possible.
I will provide an example of what is going on:
Firstly, I am using VS2017 (latest revision) EF 6, Automapper and GraphDiff.
I have a table which contains the following data.
As you can see this lists data for a ParcelId of 5023, the only difference is the IsAcquired and IsCurrent flags.
I am not going into the code that updates the data with the IsCurrent flag set to true as it is very complicated, but in essence, a screen allows users to enter values, that on saving sets the records in the second list from IsCurrent to False and inserts Three new records that have new values and has the IsCurrent set to True. This provides us the ability to undo these records.
Now, I have differnt screen that enables you to edit the main data, or in other words the data from the first grid.
This is using GrphDiff to update the data. The data that is in the second grid is NOT recovered for this edit, but on saving the GraphDiff opertaion is seeing that the data is different and overwriting in.
dbContext.UpdateGraph(a,map=>map.OwnedCollection(x => x.ParcelRight);
I need it to ingnore the records that an IsCurrent equals true and only update records that have IsAcquired = true.
I tried:
dbContext.UpdateGraph(a,map=>map.OwnedCollection(x => x.ParcelRight
.Where(r => r.IsAcquired == true).ToList());
but it did not work.
I found the following which sort of implies that it cannot be done.
Research
Thanks to all that looked at this, but it looks like it is something that causes GraphDiff issues, so I have changed my code for this update to use a more traditional Linq to Entites solution.

C# WPF Database Exercise How to update database column

Doing a learning exercise.
Trying to update the database date column for all entries to a new specific value or go through each entry and change date to a new specific value.
I tried using DataContext & Linq but it keeps telling me missing reference which its not so I have reverted to this.
var results = webDataSet.GreyList;
foreach (var elements in results)
{
elements.Date = 55;
}
webDataSet.AcceptChanges();
greyWebTableAdapter.Update(webDataSet.GreyList);
Even If i put Update in a try catch it says it is successful but it will never update the database.
Plus I'd like to thank the people who have nothing to say yet down vote my questions, its people like you who really bring the community together.
To anyone else who took advice to add .AcceptChanges(); by using this it sets the dataSets modified row value from true to false; so when you update the method looks for modified true row's however they are all false so nothing gets updated. Also the other factor to not seeing the database change is because Visual studio 2015 creates a copy of the database from your local folder and duplicates it in your bin folder, so looking for changes in your local folders database is a waste of time.

What the most efficient way of monitoring changes to data on an ASP.Net form?

I have an ASP.Net form and I want to send an email when the user changes their data. The email should only include data that has changed, and there are about 15 data fields total.
I don't want to use an ORM since I am updating a website that a 3rd party built for us, and all their data access calls go through a custom library of theirs.
The only ways to do this I can think of is
Make another database call to get old values and compare the form values one-by-one. If they're different, append to the email.
Store original data somewhere when it's first loaded (hidden field, session, etc), and once again compare the data one field at a time and append the differences to an email
Have someone on SO tell me there's an easier and/or simpler way that I haven't thought of
All the text boxes will have a TextChanged event, you can have them mark themselves as modified. ComboBox's will have a SelectedIndexChanged event, and so on.
Edit: All changed events can check their initial values (even on reverted changes) and either mark themselves as still modified or on a revert, as un-modified.
Here are some suggestions that may / may not be useful:
Trigger on the database table and the trigger compares the old (using the DELETED table) and updated (using the INSERTED table) and then sends an email. This may or may not be viable and I am not a big advocate of triggers.
Like you have already said you could make another database call, which would be my reccommended approach.
From what you've said I think that the only way forward is to create a duplicate dataset on the form to store the old data and run a comparison at the point where you want to produce the email.
You can use Dataset.Copy to copy structure and data.
However, now that I think about it there's always the Datset.GetChanges() method and the Dataset.AcceptChanges() along with DataSet.HasChanges()
Example code from this link:
if(dataSet.HasChanges(DataRowState.Modified |
DataRowState.Added)&& dataSet.HasErrors)
{
// Use GetChanges to extract subset.
changesDataSet = dataSet.GetChanges(
DataRowState.Modified|DataRowState.Added);
PrintValues(changesDataSet, "Subset values");
// Insert code to reconcile errors. In this case, reject changes.
foreach(DataTable changesTable in changesDataSet.Tables)
{
if (changesTable.HasErrors)
{
foreach(DataRow changesRow in changesTable.Rows)
{
//Console.WriteLine(changesRow["Item"]);
if((int)changesRow["Item",DataRowVersion.Current ]> 100)
{
changesRow.RejectChanges();
changesRow.ClearErrors();
}
}
}
}
// Add a column to the changesDataSet.
changesDataSet.Tables["Items"].Columns.Add(
new DataColumn("newColumn"));
PrintValues(changesDataSet, "Reconciled subset values");
// Merge changes back to first DataSet.
dataSet.Merge(changesDataSet, false,
System.Data.MissingSchemaAction.Add);
}
PrintValues(dataSet, "Merged Values");

SQL column true or false - use a view?

Simple question, I have an application and dependant on whether you are in the administration system or on the public website I want to show different results.
Example: in the database for a news story in the administration I may set the column value 'showonsite' to false. So I would like this to show in the administration panel only and not on the live site.
My question is, because I require the same information just with the only one column change, live site to only show true values and administration to show both. What is the most effective way of achieving this without copy paste of code?
Thanks
Please see the second query.
I may be missing something. For non-adminstrative users, could you simply not SELECT news stories with the showonsite column set to false?
For example:
SELECT
*
FROM
dbo.NewsStory
WHERE
showOnSite = 1
Edit:
Oh! I see. You're talking about copying and pasting the query. It's late. >.<
If you have a stored procedure, you can pass a value to indicate whether the given user is an administrator:
SELECT
*
FROM
dbo.NewsStory
WHERE
showOnSite = 1
OR #isAdmin = 1
Depends on where you write your code - if you use stored procedures, then just a parameter like #liveonly should be sufficient. Sameway if you use an inline sql query directly in a C# method, then a parameter live_only should be good enough, to determine whether the extra where condition will be added or not.
For eg. in the SP
SELECT *
FROM news
WHERE ((#live_only=true AND showonsite=true) or (#live_only=false))
This way it can be called with #live_only = false for admin panel, but with value true for the actual site.
No, I wouldn't use a view for that, an I wouldn't copy any code. It sounds like this is just a conditional filter on your queries.
You don't make it clear how you are doing the data-access, but this might mean aasdij an extra line of TSQL, adding adding a so parameter, adding an extra LINQ .Where clause, etc

Categories