Trouble deleting a record

Feb 25, 2011 at 12:26 AM

The following code:

MList<EmeDN> emes2Delete = Database.Query<EmeDN>().Where

                       (e => e.RefName == constructionName

                       && e.IsOn == stratum).ToMList<EmeDN>();

                   foreach (EmeDN e in emes2Delete)

                   {

                       MessageBox.Show("Need to delete eme called '" + e.RefName + "'.");

                       Database.Delete<EmeDN>(e);

                   }

Gave me the following error: "Entity of type EmeDN and id 2 not found."

but a look in LinqPad at the database shows that table TlEmeDN has 2 records as follows:

Id   ToStr   Ticks                                RefName   Highlight   IdIsOn

1   Mfaith   634341640444531250   Mfaith        1                1

2   Mfully   634341640461250000    Mfully        1                1

 

Can you tell from this code why I cannot delete this object?

Coordinator
Feb 25, 2011 at 8:16 AM
Edited Feb 25, 2011 at 8:17 AM

Hi Hezek1ah

I don't fully remember it but i think V 1.0 had some problems returning the number of removed records when there was collections inside.

We are about to release Signum Framework 2.0, send me an email to olmo@signumsoftware.com and I will provide you a LINQ to download the beta that, SF2.0 surely will have this problem fixed. 

(BTW, it's not necessary to use MList as long as is not a colleciton inside of an entity, or for WPF binding scenarios)

Kind regards, 

Olmo

Feb 28, 2011 at 3:23 PM
Edited Feb 28, 2011 at 3:34 PM

Hi Olmo,

Thank you for the link to the beta of SF2.0

While waiting for the link, I came up with the following workaround. Each class in my model has a controller class. Each controller is responsible to delete the necessary relationships before deleting the instance. The following two methods are used by the controller classes. There is no error checking, the code duplication screams 'Refactor Me!' and I now have my magic connection string pasted in 3 different places in my code, but I am willing to live with that until version 2.0 of the Signum Framwework is released.

public void DeleteRelationship(string className, string relationshipName, string whereClause)

{
   SqlConnection sqlConn = new SqlConnection(<connectionstring>);

   sqlConn.Open();

   string tblName = "Trtl" + className + relationshipName;

   SqlCommand sqlComm = new SqlCommand("DELETE FROM " + tblName + " " + whereClause, sqlConn);

   sqlComm.ExecuteNonQuery();

   sqlConn.Close();

}

public void DeleteObject(string className, string whereClause)

{

   SqlConnection sqlConn = new SqlConnection(<connectionstring>);

   sqlConn.Open();

   string tblName = "Tl" + className;

   SqlCommand sqlComm = new SqlCommand("DELETE FROM " + tblName + " " + whereClause, sqlConn);

   sqlComm.ExecuteNonQuery();

   sqlConn.Close();

}

Coordinator
Feb 28, 2011 at 7:55 PM

Hi Hazek1ah, 

I hope we find time to release the SF 2.0 sooer or later, it has many new features, only related to deleting element: 

* Deleta removes relations and actually works :) 
* EntityEvents before (Deleting) and after (Deleted)
* A LINQ way of Deleting using a query (UnsafeDelete)
* EntityEvents before UnsafeDelete

On the other side, let me give you some advices to make your temporal code more 'Signum Friendly' and not that low level:

* You don't have to create the SqlConnection manually, it's handled automatically by using the Connection and Transaction class. (Transaction.CurrentConnection and Transaction.CurrentTransaction).
* Create a SqlPreCommand instead and just execute it, just one line, it opens the connection: new SqlPreCommandSimple("DELETE FROM " + tblName + " " + whereClause).ExecuteNonQuery()
* Use Schema.Current.Table<T>().Name to get the current name of the table

public void DeleteObject<T>(string whereClause)
{

   Table table = Schema.Currentt.Table<T>(); 
   new SqlPreCommandSimple("DELETE FROM " + table.Name + " " + whereClause).ExecuteNonQuery();
}

The framework already knows how to deal with SqlConnections and SqlTransactions in the low level, by not using you can globally change the connection string using ConnectionScope class and deal with transactions in a unified way.

 

Hope it helps

 

Olmo