Using ADO datatable copy() to restore original table data - ado.net

I have the datatable bound to a datagrid where the user can see the changes he/she's making. I make a copy of the table before changes start so that I can put the original data back if the user decides not to accept the changes.
Making the copy uses very simple syntax (VB):
Dim copyDataTable As DataTable
copyDataTable = dataset.table.Copy()
However, reversing the syntax to:
dataset.table = copyDataTable
Gives "dataset.table is read only."
The only example I can find for using datatable Copy() is to create a new table, not copy back to an existing one.
I suspect there is some simple syntax or method, equivalent to making the copy, but so far no luck in finding it.
Anyone familiar with how to do it, or even a different approach to what I'm trying to do?
Thanks,
Chas

The solution is a different and much simpler approach answered on MSDN:
Actually, if the user doesn't want to save the changes, all you need to do is dataset.RejectChanges(), which will put your DataSet back to it's original state (assuming you haven't issued an .AcceptChanges() at any point).
~~Bonnie Berent DeWitt [C# MVP]

Related

Implement the Lead conversion using custom button

I will need to create a Custom Button "convert lead" that will perform the same functionality as Standard Button "Convert" when the button is clicked.
What is the best approach to do it..?
That's a very broad question. What exactly you need, what have you tried so far? Do you really need just a button that opens the conversion page or something more?
If you want to somehow recreate it with Apex... Core of the coded solution would be the Database.convertLead method. You don't pass to it whole leads (like to Database.insert for example) but instead just their IDs + bunch of control flags to make it do exactly what you need. Read up about LeadConvert object. And similarly you can get Account/Contact/Opportunity ID from the result object if it succeeded.
I don't think there's programmatic way to access field names & mappings defined by administrator for lead conversion. Maybe you'd need to store this info somehow (in helper object? custom metadata?). So then you'd query the field names from metadata, then query the lead fields and finally display table of fields & mappings to the user.

Entity Framework Context Not Acting As I Expected

I am seeing something in Entity Framework that has me thinking that I either completely misunderstand how the database context works, or EF is actually broken (and I know that most likely means I just don't get it).
Consider the following scenario:
In the database I have a bunch of Student Attendance records, and they all have a code marked as P for present.
Then we have something akin to the following:
public void SetAttendance(int dayId,int attendanceId, int attendanceId, String mark)
{
updateAttendance = new StudentAttendance()
{
Code=String.Empty,
AttendanceId=attendanceId,
DayId = dayId
};
context.Attach(updateAttendance);
//I don't save changes yet because I now need to do some logic
var markedAttendanceCount = context.StudentAttendance.Where(att=> !String.IsNullOrEmpty(att.Code) && att.DayId == dayId).Count();
var allAttendanceCount = context.StudentAttendance.Where(att=> att.DayId == dayId).Count();
var updateDay = new ClassDay()
{
DayId = dayId,
AllMarked = markedAttendanceCount = allAttendanceCount
};
context.Attach(updateDay);
context.SaveChanges();
}
I would expect that if I were to call that SetAttendance method as follows:
myworker.SetAttendance(10,20,String.Empty);
That it should properly recognize that the attendance for the day is not fully marked. What I am instead seeing is that my look int query against context.StudentAttendance is asking the database. As such, my detection of the day's status change is always one behind.
I thought that the context was basically supposed to be smart enough to let you write something like this. In essence, I had always had the impression that the db context lets you essentially work with a serializable transaction kind of behavior. As you make changes to the data through your context, those changes will reflect in queries against the context. Am I missing something?
EF doesn't work that way, no. For performance reasons basically.
However, context.StudentAttendance.Local exposes a set containing the added entities. It also contains any entity previously loaded by the context in a query. If you like you can load the whole DbSet into memory as described here: https://msdn.microsoft.com/en-au/data/jj592872.aspx however this is not advisable for large datasets.
Also, you should be using context.Add() rather than context.Attach(). The latter is for entities which already exist in the database.
It's true that you don't fully understand how EF works, but I think EF is to blame for that. You're asking a very good and valid question.
NHibernate, as opposed to EF, has this AutoFlush feature. This means that "at any moment" it may commit changes to the database in order to keep local changes and database content in sync without the developer's intervention. In your case, it would have saved the new StudentAttendance before querying existing ones from the database. So if the new one matched the predicate (DayId == dayId) it would have contributed to allAttendanceCount. This feature, when understood well, allows for a very intuitive way of dealing with data, exactly the way you expected EF to behave.
The truth is, however, that AutoFlush has always eluded developers, so they often just disabled it. As a developer you want to have full control, you don't want to depend on some smart feature that seems to have a life of its own. (Even though the reality is that you probably just didn't take the time to fully get it).
I can imagine that for this reason, the EF team decided not to implement such a feature.
So what to do in your case? Not easy. When after adding the new StudentAttendance you'd do...
context.StudentAttendance.Load();
(assuming that you have a DbContext, though your "context.Attach" doesn't seem to be in line that).
And then...
var allAttendanceCount = context.StudentAttendance
.Local // <= Local! Includes the new item
.Where(att=> att.DayId == dayId)
.Count();
...you'd have the desired result. But of course, loading all StudentAttendance records locally is a tremendous overkill.
One simple alternative is to to the count as you do now and add 1 to it.
Another alternative is to mimic autoflush, sort of, and save the new StudentAttendance before doing the count. But then you'd have to wrap everything in a TransactionScope. One advantage is that you'd have the very latest value of allAttendanceCount.

Retrieving Drools fact from main scope (Scala)

I'm currently inserting an object into Drools working memory and running rules on it (creating a new object rather than updating the old one since I'm using Scala immutables...). From what I've understood, typically you would say something like update(myobject) and that would update the original variable inserted, letting you use the updated myObject in the main scope once the rules have been fired.
Since the objects I'm using (and inserting to memory) are immutable I can't simply modify them, and I'm having to create copies of them with slight tweaks.
Is there a way to return an object created within a rule's RHS? Perhaps by calling its FactHandle? Also open to other workarounds...
Alternatively, can I create a new object (newObject) and assign it the original's (myObject) FactHandle? Would that give me the access I need?
(Once again, I'm looking for a workaround to get Scala and Drools to work together.)
As far as I understand you problem, you could create a copy of the object with the tweaks you need and then you retract the old object and insert the new one. Something similar to:
val newObject = myObject.copy(foo = "bar");
retract(myObject);
insert(newObject);
I hope, it helps
After looking around and some prolonged trial and error I realised that FactHandles didn't quite work the way I expected. I was under the impression that they were an ID assigned to an object and that updating the object would mean that it kept its FactHandle (apparently not).
I went about this by creating a new (Scala) object and running update in the RHS of the rule as follows:
update(kcontext.getKieRuntime().getFactHandle(myObject), newObject)
While this worked fine within the rule-firing process, it was tedious to retrieve the object from the Main app afterwards. Calling ksession.getFactHandle(myObject) on the original object returned null after the rules had been fired and, as it turns out, the FactHandle of this object had indeed changed when checked by printing it out from within a rule.
The workaround for this was to save the original object's FactHandle before firing the rules (i.e. val objectFH = ksession.insert(myObject)) and to call .getObject using that FactHandle after the rules were fired (even though the FactHandle saved in this variable had changed).
In all honesty, I'm still unsure about why this works since the FactHandle changes on update, however I'm pretty sure this stems from my lack of understanding on how FactHandles work. If anyone would care to elaborate in the comments I'd be more than happy to add it in the answer for future reference.
(Thanks to #laune for helping point me back to my previous questions)

Why does the Function Module name of a Smartform change (sometimes)?

Not really critical question, but i'm curious
I am working on a form and sometimes the generated function name is /1BCDWB/SF00000473, and sometimes /1BCDWB/SF00000472. This goes back and forth.
Does anyone know what's the idea behind this? Cuz i'm quite sure it's not a bug (or i might be wrong on that).
It is not a bug. You always have to use SSF_FUNCTION_MODULE_NAME to determine the actual function module name and call it dynamically using CALL FUNCTION l_function_module.
Smartform FMs are tracked by internal numbering and thats saved in the table STXFADMI. You would always notice the different number in Development System if you have deleted any existing Form. Similarly, you would also notice the different number in your Quality system based on the sequence the forms are imported in QAS and the forms as well (as test forms are not migrated to QAS.
Similar behavior is also true for Adobe Form generated FMs.
You need to understand that every smartform has a different interface and hence the automatically generated function module needs to have different import parameters.
Due to this reason the 'SSF*' FMs generate a FM specific for your smartform. The name of the 'generated' FM changes when you migrate from one system to another. And that's the reason why you should use a variable while calling the 'generated' fm and not hardcode it.
The same goes with Adobe form as someone has rightly said in this thread.

Drupal - dynamic options for text_list field

I have a custom node type for which I want to have a field that uses a special combobox based on list_text. When one chooses the type list_text it is normally possible to enter a static list of selectable texts, however, I want this list to be dynamic, i.e. based on the results of a db_query. What is the best way to do this using Drupal 7?
A simple example for clarification: A node of this custom type X contains a field that points to another node, so whenever a node of type X is created I want a combobox that contains all other nodes.
(Best solution would be to only display the combobox during node creation, and no longer during edit. But I could also live with it if the combobox was shown during the edit as well.)
I have tried to customize options_select by defining my own data type and implementing hook_options_list accordingly. The combobox was displayed during creation with the correct values, however, I could not save it.. I have no idea what went wrong there, but on the first submit it would change to a different theme, and when I tried again I got an internal server error. Am I on the right track at all with defining a completely new data type for the field? there surely must be a simpler way?
You're right in that you don't need a new datatype. Here's a good tutorial on how to do this. It's not specifically for D7 but I didn't see much that wasn't still applicable. There may be a better way to do it in D7 specifically but I would love to know it too if so :)
The tutorial linked by allegroconmolto sent me on the right way. Thanks for that.
Here's the simpler way of doing it: tutorial
Basically, it is, as I assumed, a common problem and hence a simple solution for it was included in the webform module by now. It provides a hook_webform_select_options_info which can be used to register a callback method. The callback method is then called each time a corresponding option select of a webform is shown, so that you can easily fill it with the results of a dbquery or anything else. Works like a charm and takes next to no time to implement.