Article: AN0002444Updated: 10.11.2020
In certain case we need to physicaly delete a record, however, Objectgears prevents doing that because the record is referenced by other records. With logocal deletion there would not be any problem, but with physical deletion all the related records }those that refer to the record) have to deleted first or they have to be at least updated not to keep any reference to the record that we want to deleted.
In our example there is a record according to the figure below. The record is showing User but this is not an ObjectGears user, but the same type of record like any other. We can see two master-detail relations at the record. However, also other classes, not only those from the two displayed master-detail relations, can refer to the record. In such a case we do not want to delete the record but we will let the user to sort out these collisions manually.
We will create a button that will check whether the record is referenced from other relations. If so a message will be displayed showing which relation is used. If not, records from the two displayed master-detail relations will be deleted and finally also the records of the User. This will save time because in the above example the user would have to delete eight records from master-detail relations in total and lastly also the actual User record. This will be done here after clicking the button all at once.
if (OGActualDataRowId != null)
{
var m = OGDataParent.Model;
//check for x relations - if they exist nothing will be deleted
//...check of class "model storage"
var clf = m.ClassDefs['model_storage'];
var f = OG.DataRow.GetDataRowFilter(clf.Id);
f['service_user'] = OGActualDataRowId;
if (OG.DataRow.ExistRowByFilter(f))
{
var s = OG.TextUtils.Format(OG.MessageLoc.GetText(m.Id, 'user_record_in_class'), clf.Name);
OGForm.SetError(s);
return;
}
//...check of class "model print"
clf = m.ClassDefs['model_print'];
f = OG.DataRow.GetDataRowFilter(clf.Id);
f['service_user'] = OGActualDataRowId;
if (OG.DataRow.ExistRowByFilter(f))
{
var s = OG.TextUtils.Format(OG.MessageLoc.GetText(m.Id, 'user_record_in_class'), clf.Name);
OGForm.SetError(s);
return;
}
//...check of class "link charge to service"
clf = m.ClassDefs['link_charge_to_service'];
f = OG.DataRow.GetDataRowFilter(clf.Id);
f['service_user'] = OGActualDataRowId;
if (OG.DataRow.ExistRowByFilter(f))
{
var s = OG.TextUtils.Format(OG.MessageLoc.GetText(m.Id, 'user_record_in_class'), clf.Name);
OGForm.SetError(s);
return;
}
//actual deletion
var clSUA = m.ClassDefs['service_user_allocation'];
var colSU = clSUA.Columns['service_user'];
var sql = OG.TextUtils.Format(
'delete from DataRow{0} where {1} = {2}',
clSUA.Id, colSU.DBColumnName, OGActualDataRowId);
OG.Sql.RunSql(sql);
var clAGM = m.ClassDefs['ms_ad_group_members'];
var colSU2 = clSUA.Columns['service_user'];
var sql = OG.TextUtils.Format(
'delete from DataRow{0} where {1} = {2}',
clAGM.Id, colSU2.DBColumnName, OGActualDataRowId);
OG.Sql.RunSql(sql);
var sql = OG.TextUtils.Format(
'delete from DataRow{0} where Id = {1}',
OGDataParent.Id, OGActualDataRowId);
OG.Sql.RunSql(sql);
OGForm.RedirectTo(OGDataParent.ListUrl);
}
We are working in the script with the object OG.MessageLoc. There is a message with code user_record_in_class created in our solution. English version of the message is: "User has a record in table '{0}'. Deletion was cancelled." Expression '{0}' will be replaced by the name of the related class that was identified in the script.