What model structure should I use for tracking changes? - asp.net-mvc-3

I have a data model that requires tracking changes. I could have as many ~100,000 changes/updates to my model per month. My model involves tracking HOW a task is completed and can be broken down into 3 basic types.
I currently have my model like this but have divided the types of sandwiches into 3 separate controllers because each sandwich is made very differently:
public class Sandwich
{
public int Id { get; set; }
public int SandwichTypeId { get; set; } //This is an enum type
//About a dozen other properties that define HOW the sandwich gets made
}
I could break it apart like this and match it more to my controllers:
public class PeanutButterAndJellySandwich
{
public int Id { get; set; }
//No enum sandwich type
//About a dozen other properties that define HOW the sandwich gets made
}
public class HamSandwich
{
public int Id { get; set; }
//No enum sandwich type
//About a dozen other properties that define HOW the sandwich gets made
}
//etc
2 Part Question:
Is there any advantage(s) to breaking up the model?
If so, would those advantages be defeated because I would have to add separate tracking tables as well?
Thanks.

In EF I have done something like subclassing the Sandwich class, and using those in the specific controllers.
On the other hand, I've handled things like this by, for example, creating just one more field:
public class Sandwich
{
public int? CurrentVersion { get; set; }
public int Id { get; set; }
public int SandwichTypeId { get; set; } //This is an enum type
//About a dozen other properties that define HOW the sandwich gets made
}
This way, a single sandwich can have a lot of previous versions, all of which would point to the current one. In my update routine, I created a duplicate (with the old version's CurrentVersion pointing to the original, now updated, version Id).
This of course requires you to change other places where you list Sandwiches to look only for those which are not revisions.
If you need to reference immediately previous or next versions then you could create int? PreviousVersion and/or int? NextVersion to avoid searches in your database.

Related

Xamarin: why need the BusinessEntityBase class

I want to learn Xamarin and i took a look at a sample project called 'Tasky'
But i don't understand why theres a BusinessEntityBase class...
A task also needs it's ID to be PK and incremented so why doesn't it implement
the BusinessEntityBase class instead of the IBusinessEntity interface?
public class Task : IBusinessEntity
{
public Task ()
{
}
[PrimaryKey, AutoIncrement]
public int ID { get; set; }
public string Name { get; set; }
public string Notes { get; set; }
// new property
public bool Done { get; set; }
}
public abstract class BusinessEntityBase : IBusinessEntity
{
public BusinessEntityBase ()
{
}
/// <summary>
/// Gets or sets the Database ID.
/// </summary>
[PrimaryKey, AutoIncrement]
public int ID { get; set; }
}
public interface IBusinessEntity
{
int ID { get; set; }
}
IBusinessEntity interface is just that - an interface, the properties of which (in this case, ID) would be a part of every business entity. Read up on the use of Interfaces in C# to get a better understanding of why this is done.
Another example would be:
Lets say you have an employee management application which contains three different kinds of users - Manager, Developer, Tester. You have a class for each of these.
It is very likely that all three of them contain an ID field, a first name and a last name.
Instead of adding the same properties to each of their classes, you create an interface called IEmployee, which has three fields - ID, FirstName and LastName and get each of the three classes to implement it.
Functionally, implementing the properties on an interface and adding them manually has the same effect on the class. Although, having an interface connecting all three of them, you now have a more abstract way to access your data (For example, to count the number of employees, you could check the count of IEmployee objects, rather than counting all three separate and then adding the numbers up).
TL;DR Doing it this way is not mandatory. In this scenario you could simply have a BusinessEntity class that has an ID field. It is simply a good practice and makes your applications easy/possible to maintain when they grow.

Event versioning in CQRS

We are at a point in our development cycle (asp.net mvc applciation), where we need to introduce changes to our existing commands and events (say adding/removing a few properties etc).
I have been trying to find a way to introduce commands/events versioning in the system. I have read many posts on google/stackoverflow etc but am still to see an example of code that implements it. Is there a recommended pattern one should follow when versioning. If yes any examples/snippets?
Edit: This is how far i have gotten with this
i have versioned my events backwards, such that the latest will always be called the same, while the ones that go obsolete will have a suffix added to it like '_V1', '_V2' etc.
So if i have an event
public class OrderSubmittedEvent : IDomainEvent
{
public int OrderId { get; private set; }
public OrderSubmittedEvent(int orderId)
{
OrderId = orderId;
}
}
and if i have to add a few properties i rename my event above to
public class OrderSubmittedEvent_V1 : IDomainEvent
{
public int OrderId { get; private set; }
public OrderSubmittedEvent_V1(int orderId)
{
OrderId = orderId;
}
}
and introduce another event with the same name as my original event but with added properties, like so
public class OrderSubmittedEvent : IDomainEvent
{
public int OrderId { get; private set; }
public OrderSubmittedEvent(int version = 1, int orderId = 0, string customerName =
"Joe blogs", string address = "Earth")
{
OrderId = orderId;
CustomerName = customerName;
Address = address;
CurrentVersion = version;
}
public static int LatestVersion
{
get { return 2; }
}
public int CurrentVersion { get; set; }
public string CustomerName { get; set; }
public string Address { get; set; }
}
i still have to go ahead and change my code which publishes this event to include values for new properties.
any given point of time when i get all my events from the event store (say, for replaying) they will always be of the same type after deserialization (in this case OrderSubmittedEvent) with new properties which were not part of the old events populated with their default values.
At the time of replaying my events i make my events go through an IEventUpgrader
This first verifies if the events is the latest version available. since the type will always be the event type, this check is based on the properties "LatestVersion" and "CurrentVersion"
what does everyone think of this approach?
next todo
If event is an old version publish an 'UpdateMYEVENT' Event
thanks
usually you only need to version the events, you can ignore the commands since you don't store them in the event store.
There are few ways to implement versioning.. my method is quite simple:
[Obsolete]
public class CompanyCreated
{
public Guid Id { get; set; }
public string Name { get; set; }
}
public class CompanyCreated_V2
{
public Guid Id { get; set; }
public string CompanyName { get; set; }
public string TaxNumber { get; set; }
}
You need to handle conversion of events from the old one to the new one as you read the events from the event store.
also, you need to be aware that you never remove any old event classes, hence why I decorate them as Obsolete, to let other developers know not to use the event.
If you are only adding & removing properties, there might be no need to version events; just ignore the serialized properties that are removed, and use sensible defaults for the ones you add.
I would be cautious with mixing events and commands. They have different purposes and solve different problems.
To give a better feeling of what I mean, think of it like so
Commands are more like RESTful API, client-server communication.
While Event Sourcing is more of a way to store the data.
Both need versioning as a way to provide backward compatibility through immutability, but once again for different reasons. Hence implementation and exceptions are different.
I would definitely recommend a book Event Versioning by Greg Young to get more insides into versioning for event sourced systems..
For more information on the commanding, check out the CQRS series and particularly CQRS via HTTP.
Admittedly I have not had the opportunity to try the following but I'd like go bake in the versioning from day one:
Since the full type name is relevant I would go for namespaces.
namespace Primary.Messages.V1
{
public class CompanyCreated
{
public Guid Id { get; set; }
public string Name { get; set; }
}
}
namespace Primary.Messages.V2
{
public class CompanyCreated
{
public Guid Id { get; set; }
public string Name { get; set; }
public string TaxNumber { get; set; }
}
}
These could be in different assemblies and you could mark the older ones as obsolete (as suggested by Sarmaad). It may be that older version are not necessarily obsolete though.
Any ideas?
I am totally out of reasons while considering why would one need event-versioning the way it has been asked in question and more specifically the way it has been suggested in the answers?
I can think of only two use cases
1- the event class currently being used is deprecated and no more needed.
Then that class can be tracked down in the git anytime needed. So why bother and complicate the active code by keeping the dead classes?
2- The business requirement is changed and now you need to keep the base event but you also need another similar event with some parameter differences.
That can be solved in a number of ways, like decorator pattern can help to handle such variations to a great extent
Alternately the new event might be representing a unique domain concept and instead of trying to force the concept into existing model, it might be better to name it more semantically and use it that way.

EF, POCO, DB First... how to do Business Logic in Property "set"?

OK, so I've been building my first large(ish) EF 4.1 POCO + MVC application. It's a replacement of a legacy system so I 'm using an existing database.
I've generated my POCO classes using DbContext T4 generation. I've got some really nice forms going on and some really nice validation happening with a lot of sexy generics in my MVC classes to cut down on boiler-plate code... All's good.
Suddenly I realized that the most sensible thing (to me) would be for some of business logic to be in the "set" of some of the properties of my POCO objects.
E.g. Suppose the following class was generated by the T4;
public partial class SalesOrderLine
{
public int ID { get; set; }
public int SalesOrderID { get; set; }
public int ProductID { get; set; }
public decimal UnitPrice { get; set; }
public int Quantity { get; set; }
public decimal ExtendedPrice { get; set; }
public virtual Product Product { get; set; }
public virtual SalesOrder SalesOrder { get; set; }
}
Ignore for a moment the obvious argument that the calculated field "ExtendedPrice" shouldn't even be stored in the database, and just come along with me for the ride...
...then, it seems to me, logically, if this object is really supposed to represent a Sales Order Line, that I should be able to construct my object such that the following unit test will work:
SalesOrderLine sol = new SalesOrderLine();
sol.UnitPrice = 100;
sol.Quantity = 5;
Assert.IsEqual(sol.ExtendedPrice, 500);
...obviously I can't do that as long as I want the base POCO to be generated by the T4. It seems to me I have several options:
Set the generated code file's properties "do not compile", copy and paste the generated code into another file and modify the "set" to do the business logic of setting the extended price when the UnitPrice or Quantity is set. The downside here is that the logic will be run whenever an object is loaded from the database (since the EF will set the public properties and not my private fields). Additionally, this object will then need to be maintained manually for the rest of the life of the project when database changes occur.
Create an UpdateTotals function that gets called in the Validate routine that I have for my object, which gets called by the SaveChanges() on the DbContext. Obviously, the above Unit Test above would not work in that case. The system, and my integration tests however would work and would only call the code when a change was done to the object.
Decide that I'm asking the wrong question, and that I should really add methods to the object called "SetPrice" and "SetQuantity", and then qualify the set accessors of the UnitPrice and Quantity to be "internal". The downside here is that MVC will try and update the model from the form and won't be able to set those properties.
Some solution that involves downloading two or three more frameworks that create even more levels of abstraction than I already have... A repository pattern, or "use NHibernate" or something like that... You can suggest this, but I'm growing weary of how much work it is to set things up to do it the "academically correct" way. For this project, I'd rather meet halfway on the long-term-maintainability vs. speed-of-development spectrum and not over-complicate my project with a ton of extra tools and dlls... ...but I'll try an keep an open mind :)
--- EDIT: another idea ---
[5.] Another thought, since the fields are always simply calculated there should really be no need to ever set them - either from the database or otherwise. Therefore, something like this might work:
public decimal ExtendedAmount
{
get { return UnitPrice * Quantity; }
internal set { }
}
...my thought is that the EF instantiation would attempt to call the "set", but the set would do nothing, then, when the object was saved or checked for changes it would call the 'get' and that would return the calculated value and that value would get stored in the DB. The only downside here is when you were trying to use the object model to validate the database when the database had in incorrect value stored in the ExtendedAmount field. It's a little hokie, I know, but I thought it would be an interesting trick... in fact the "set" could perhaps throw an exception if (value != UnitPrice * Quantity)
--- END EDIT ---
I'm curious to hear what other have done in these kinds of cases, as I'm sure it's common. Seems like a lot of the tutorials take you as far as "generating POCO classes from the database", and then leave the rest of the project development up to you.
Cheers,
Chris
A couple ideas:
Why not use Code First? That way, you can put business logic (e.g., calculated properties) right in your entity class.
Example
public partial class SalesOrderLine
{
public int ID { get; set; }
public int SalesOrderID { get; set; }
public int ProductID { get; set; }
private decimal _unitPrice;
public decimal UnitPrice
{
get { return _unitPrice; }
set
{
if (value == _unitPrice) return;
_unitPrice = value;
CalculateExtendedPrice();
}
}
private decimal _quantity;
public decimal Quantity
{
get { return _quantity; }
set
{
if (value == _quantity) return;
_quantity= value;
CalculateExtendedPrice();
}
}
public decimal ExtendedPrice { get; set; }
public virtual Product Product { get; set; }
public virtual SalesOrder SalesOrder { get; set; }
private void CalculateExtendedPrice()
{
ExtendedPrice = UnitPrice * Quantity;
}
}
If Code First is not an option, what about making your entity a partial class (if it is not already) and putting your business logic in a separate code file (but with the same class name). This way, your main code file will get overwritten when you generate, but your secondary code file will remain. This is the usual way to deal with generated code.

How to make single controller for two database classes - MVC3

I have two database classes as defined below:
public class TopDate
{
[Key]
public int DateId { get; set; }
public DateTime Date { get; set; }
}
public class TopSong
{
[Key]
public int SongId { get; set; }
public string Title { get; set; }
public int DateId { get; set; }
}
where DateId is foreign key to TopSong
I am creating a controller through which i can create, delete or edit these database values.
When i right click on controller class and add controller i can only select one of the two classes defined above. Is there a way to make 1 controller to handle database updates to both these tables on one page?
Error Image:
Your controller should not be dealing directly with domain objects (meaning those things that are directly associated with your database). Create a ViewModel that contains the properties that you need, use your service layer to populate the ViewModel and your controller will use that as the Model for its base. An example of your ViewModel could be something like the following given your description above:
public class MusicViewModel
{
public int SongId {get;set;}
public string Title {get;set;}
public IEnumerable<DateTime> TopDates {get;set;}
}
This view model would contain a list of all dates that a specific song was a Top Song.
The objects you showing (code) are database classes (so called domain objects).
What you need to do is to define a view model, a standard ASP MVC practice:
you define a class, that is tailored for specific view and only containing data relevant to that particular view. So you will have a view model for a view that will create a song, another that will update it etc.
Actually situation you describing is classical situation to use view models. Using domain objects in the views, however, is really really bad practice and prone to more problems than you want to deal with.
Hope this helps.

In ASP.NET MVC3 how do you stay DRY with very similar but slightly different viewmodels?

In building an app, we created a generic object model to store some values, the viewmodel looks a bit like this at the moment:
public class FooViewModel {
public int ID { get; set; }
public byte FooType { get; set; }
[Required]
[Display(Name = "Bar Name")]
public string Name { get; set; }
[Required]
public string Email { get; set; }
//etc, etc
}
The problem is: depending on the FooType, we want to have the Display Name to be different and the Email is not required for type 1 and 2, but is required for type 3 and 4.
We tried seperating out the properties that differ per type in to classes that inherit from this one, but the validation does a fallback on what is specified in the base type, so that didn't work.
Currently, the only option seems to be to create a viewmodel for each FooType (and also seperate controllers and view), which leads to a lot of code duplication.
What are other ways to keep this DRY?
To benefit a validation context (e.g. validating objects in different contexts), I strongly recommend using FluentValidation library.
You could implement a custom RequiredIf validation attribute, or you could implement IValidatableObject.

Resources