I’ve put together a basic web app using PetaPoco to manage a one-to-many relationship between authors and their articles.
The author poco contains just the author’s name, id and a list of articles the author has written :
public class Author
{
public int Id {get; set;}
public string Name {get; set;}
[ResultColumn]
public List<Article> Articles {get; set;}
public Author()
{
Articles = new List<Article>();
}
}
The Author.Articles list is a [ResultColumn] meaning that PetaPoco won’t try and persist it automatically, it’s ignored during inserts and updates. The Article poco has more properties :
public class Article
{
public int? Id {get; set;}
public string Title {get; set;}
public string Body {get; set;}
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode=true)]
public DateTime Date {get; set;}
[ResultColumn]
public Author Author {get; set;}
[Column( "author_id")]
[DisplayName( "Author")]
public int? AuthorId {get; set;}
public Article()
{
Date = DateTime.Now;
}
}
The Date property has a date format attribute so that in the \Article\Edit.cshtml view @Html.EditorFor(model => model.Article.Date) will display the date how I want it. The Author property is another ResultColumn only used when displaying the Article, not when updating it. In the ArticleRepository I use the MulltiPoco functionality in PetaPoco to populate the Author when the Article record is retrieved.
By default the app uses the tempdb at .\SQLEXPRESS. This is defined in the web.config :
<add name="PetaPocoWebTest" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=tempdb;Integrated Security=True" providerName="System.Data.SqlClient" />
The tempdb is always present in SQL Server and is recreated when the database is stopped and started. You can change this to suit your environment. The app will auto generate the tables for you if they don’t exist. In theory if you have SQL Express running you don’t need to do anything to get started
There are two repository classes; AuthorRepository and ArticleRepository. These classes are where the PetaPoco work lives. As well as loading the Author the AuthorRepository class also loads in the list of articles by that author. I use a relationship relator callback class as demonstrated in the recent PetaPoco object relationship mapping blog post. I made a slight tweak to handle objects that have no child objects at all otherwise there was always a new() version of Article in the list. The fix is simple :
if( article.Id != int.MinValue)
{
// Only add this article if the details aren't blank
_currentAuthor.Articles.Add( article);
}
I tried to get this working with an int? Id, but had type conversion problems in PetaPoco. I’ll investigate that later as it would be useful to have int? Id to indicate a blank record
I’ve used the Glimpse PetaPoco plugin by Schotime (Adam Schroder). Because the Glimpse plugin uses HttpContext.Current.Items all the SQL statements are lost when RedirectToAction() is called from a controller. I got around this by copying the PetaPoco Glimpse data into TempData before a redirect, and from TempData back into the Items collection before the controller executes.
This means you still see update/insert/delete SQL. It is definitely a requirement to perform a RedirectToAction() after such database calls so that it isn’t possible to refresh the screen and re-execute the commands (ie; cause havoc). If the user did refresh the screen (or otherwise repeat the last request) they’d just get the redirect to action and not the request that fired the database action.
I expect this to be a common pattern with Glimpse plugins that use response redirects.
UPDATE
Many thanks to Schotime who showed me that the Remote tab in Glimpse shows you the last 5 requests. All the SQL is there in Glimpse if you look for it. I didn’t realise this when I added the TempData solution
:) but at least using TempData the SQL commands prior to a redirect are visible right on the PetaPoco tab without having to drill down to the previous request, which I kinda like as it’s more intuitive and effortless.
Hope this is useful to someone. You can download the source at GitHub. This is my first project using git so if there are any problems please let me know.
Finally, I’ve cut my finger and I’m angry with my cat.