My program has an entity call Articles. In one form the user can specify how many new articles he wants to buy. This happens in a form called "Purchase order". So, when that happens, the stock musk increase. In another form, where I list all the articles, it must reflect that change.
Now, this is my problem. After I generate the purchase order, if I go to the SQL and I search that article in my DB, I can see the change. If go to my form, where I list the articles, I cant see that change. But, if I close the program and then I run it again, if I search the article, the change appears.
I don't know what could be the mistake. I'm using Entity Framework.
This is how I add the article.
BaseRepository.BeginTransaction();
foreach (Documento_Articulo doc in datos.Documento_Articulo)
{
if (!articuloRepository.Increase(doc.Articulo.Id_Articulo, doc.Cantidad))
{
BaseRepository.RollBackTransaction();
return response.Error("Error: - " + doc.Articulo.Descripcion);
}
}
response.Value = documentoRepository.InsertGetDocument(datos);
BaseRepository.CommitTransaction();
I think that code does not have a problem, because as I say, I can see the change in my database.
Does anybody knows why this happens?
I suspect the client caches the results. If you set a breakpoint in the method which returns the list from the db, is it executed every time you display the it?
Related
This is a contrived example however I have simplified it for ease of explanation.
Please see my update at the bottom before investing too much of your
time!
Background
I have some (a lot of) code that ordinarily queries my DB as follows:
SELECT name FROM sites where IsLive=1;
My challenge is to, under certain conditions, return the full list of sites, essentially
SELECT name from sites;
I do not wish to modify the actual C# code issuing the SQL (although I can do if I have to in order to achieve my goal which is purely for demonstration purposes).
Therefore in order to leave as much untouched as possible my thoughts are to insert a database-proxy-view called site that returns the data dependent on a control variable
Method
Rename existing site table to site_table
Create a new view named site that the C# code now unknowingly targets and which returns the (possibly filtered) details from site_table according to the control variable value (Note a limitation on variables in views meant I had to create a function in order to demonstrate this - see http://dev.mysql.com/doc/refman/5.7/en/create-view.html wrt error 1351)
Changes made
ALTER TABLE site RENAME TO site_table;
CREATE FUNCTION controlVariableFn() RETURNS VARCHAR(16) RETURN #controlVariable;
CREATE OR REPLACE VIEW site AS SELECT * from site_table WHERE (IsLive = 1 OR controlVariableFn() = 'SHOWALL');
The above statements are ugly but achieve the result I want, however my problem is to dynamically pass through controlVariable without changing my main SQL queries being sent.
My Question
Is there a way to (ideally as I am creating my connection object) define the controlVariable outside the actual SQL to be executed but which the View can still access similar to the above as though it had been supplied as a regular user variable parameter to the query?
so the code would look something like
var connectionString = "Server=localhost;User ID=un;Password=pw;Database=dbname;....";
DbConnection db = new MySql.Data.MySqlClient.MySqlConnection
(connectionString, "controlVariable=SHOWALL");
var results = db.Query<Site>("SELECT * FROM site;");
(I understand that this would not be a smart permanent solution)
Update
My preferred solution as outlined above will not work for me as once I get into my data access layer as the results set will
essentially be filtered again back to the original set. There are some circumstances where it
could work; it would depend on the SQL issued (e.g. when collapsing a
results set down instead of trying to expand a results set as I was
trying to do here).
In that regard I am no longer looking for an answer here but will leave it for posterity as a preferred option and as per the guidelines - thanks anyway.
If you do not want to edit the c# code then the variable will have to be stored in the database although i am not sure how you will not edit the code.
If you are willing to edit the code then you can access a secondary configuration table which will have the settings that you would like the user to pass to the view. take this and allow the user to select which they want and then pass it to the view through the application.
I'm writing my own Rule Engine, I've looked at a couple that existed but I'm looking for something else which I couldn't find examples to.
I'm looking for a similar application where I can dig into and learn how to do it.
Now, my question is REGARDLESS of the Rule Engine, more of a Form/Dynamic question, but if with your answer you can
relate to what I eventually want to do, that would be great.
Regarding the UI, I'm using Visual Form and the I'd like it to be like this:
http://i.imgur.com/5istREF.jpg
Now, once the user select on the final check box "And/Or" I want him to be able to enter another rule, exactly the same format as the first one.
http://i.imgur.com/N588sjj.jpg
Now the user can basically do it as many times as he wants, so I'm looking for a way to dynamically handle it and create buttons/pannels or even using the same ones (but every time he can enter different values).
Like I've said if you know any similar application/code that I can look into, regardless of rule engine, that will help as well.
Eventually I will take all the fields that he entered and turn it into code.
If I understand you correctly, what you can do is make a controller of your own which is defined in an additional form and then you can add it to your main form as much as you want.
You can define this new controller (meaning a new form) to hold only a single line of the comboBox and then add it to a location in your main form which is based on the location of the previous controller.
Here is an example which adds several control of a class called CNewControl to a tab called newControlsTab one after the other.
int controlHeight = 0;
foreach (CNewControl newControl in newControlList)
{
this.newControlsTab.Controls.Add(newControl );
newControl.Dock = DockStyle.Top;
newControl.Location = new System.Drawing.Point(40, 3 + controlHeight);
controlHeight += newControl .Size.Height;
}
You can of course change it to add your line only once when the user chooses the appropriate option in which a line should be added.
I have an online store and the software is highly customized but not completely ours. We sell tours and some of them have reservations so I added a calendar to let them pick the date/time they want. Originally each cal_SelectionChanged() call was looking stuff up from the store database and that was, of course, horribly slow. I wanted to use a Data Dictionary to get the information once and use it whenever needed.
I have this class:
public partial class ConLib_Custom_BuyTourProductDialog : System.Web.UI.UserControl
and this declared inside that class.
static Dictionary<string, string> CustomFieldDict = new Dictionary<string, string>();
I also have a function to load all the bits from a database that I'll need on my page. My plan was to call this on Page_Load() and just access the info when needed.
protected void LoadCustomFieldDictionary()
{
string _sku = _Product.Sku.Trim().ToLower();
if (CustomFieldDict.ContainsKey("Sku"))
{
// is the dictionary entry for *this* sku?
if (CustomFieldDict["Sku"] == _sku)
{
return; // already have this one.
}
}
CustomFieldDict["Sku"] = _sku;
CustomFieldDict["EventId"] = TTAUtils.GetCustomFieldValue(_Product, "EventId");
CustomFieldDict["ResEventTypeId"] = TTAUtils.GetCustomFieldValue(_Product, "ResEventTypeId");
etc.
}
Then my boss loaded a page - ok, everything was fine - and changed one of the bits of data in the database to point to a different, wrong, ResEventTypeId. Reload the page and it has the new data. He changed it back to the original and it was "stuck" on the wrong information. I loaded a browser on my iPad and went there and it fed me the wrong info as well.
It seems that the server is caching that DataDictionary and even if we change the database all visitors, even in other sessions, get this cached wrong info.
Do you think this assessment is right?
What's the proper way to do this so that a visitor changing dates gets some kind of cached lookup speed and yet another browser gets a fresh set from the database?
How do I make it "forget" what it thinks it knows and accept the new info until I fix it? Reset IIS?
Thankfully this is on a dev server and not my live store!
Thanks for your help. I've learned a lot about C# and .NET but it's shade-tree-mechanic type stuff and I lack the formal training that is out there and would really help in situations like these. Any help is appreciated!
For anyone coming by at a later time:
What Jonesy said is very true - statics are scary. I found out from one site (link to a link from his link) that statics like this are sticky to the Application Pool level so any other browser would get the "wrong" information.
For my situation I decided to use ViewState to store the info since it was small and my current V.S. isn't very large already. Beware doing this for large amounts of data but in my case it was the best.
May sound like a dumb question but here goes.
I instantiate a LIST from my homepage, the list is in a global class file, and returns all the information about the person logging in. the person, could have one or more accounts associated with the site, and therefore i need to code against a default flag to display their default account informaiton. However, i then also need to build their other account information and display this for them.
The additional account(s) are listed in a drop down box. when the drop down box fires off, instead of calling out to the class again, and retrieving all the necessary information, as i've already done this once, how can i store the object, so that it can be used?
I've looked at Session Variables, but this gets a bit messy (I have 35 fields being returned in my list), plus, the Session variables only get set the first time around, not on DDL changed.
therefore, I need a way of having quick access to the object. - what's the best approach?
As per me , Session is the best possible object for your type of requirement and on DDL changed event try to rebind the Session object with new modified values
I am creating a database application using Visual C# Express and MySQL. The issue is that I only want to store data to the database from the C# forms if the data has actually been changed, the way I do it now is that when the 'Save' button is clicked all the all the fields in the form are saved into the database, whether or not they have been changed.
The solution I have come up with is just to check for every field in the form if it has been changed and then change the SQL command accordingly, i.e.
//when the details are loaded into the form
String strOriginalName = txtFirstname.Text;
//when the save button is checked
if(strOriginalName != txtFirstname.Text)
{
String strUpdate = "UPDATE table SET firstName = txtFirstname.Text";
MySqlCommand cmdUpdate = new MySqlCommand(strUpdate, connection);
cmdUpdate.ExecuteNonQuery();
}
Does anyone else have a better or alternative solution? Thank you for your help, if I was vague in any part, please let me know and I can try explain further.
I suggest to use some OR Mapper (NHibernate) for example. It will do it all for you. In addition this will give you caching and other cool things for free :)
Lessons learned for future are priceless and your next applications will be grow faster and faster. :)
Have a single update query - unless you have hundreds of parameters, you shouldn't see much of a performance issue.
In the class that you want to update, have a boolean dirty flag that will be set to true whenever a value changes.
Only update to the database when the flag is indeed true.
Alternatively, use an ORM that implements Unit Of Work, which should handle this for you automatically.
If you have single field in the form then this is correct...
but when you have multiple values(fields) in your form then you should use 1 flag variable.
Once any text is changed you should set that flag to true and update it..
Look at the way ORMs implement this feature,
Search for NotifyPropertyChanged and Object Change Tracking.