Wednesday, March 30, 2016

Highfalutin code #4. With great power, comes great responsibility.

No matter how powerful our programming language is..

foreach (var item in 
    documentFields.SelectMany(
        documentField => documentField.Options, 
        (documentField, option) => new { documentField, option }
    )
)
{
   item.option.DocumentField = item.documentField;
}


..we still have a great responsibility to make our code readable and maintainable:
foreach (var documentField in documentFields)
    foreach (var option in documentField.Options)
    {
        option.DocumentField = documentField;
    }


SelectMany's intent is to flatten *ALL* the option collection from all fields, and then assign each option item in collection to their parent field.

Though the objective of the first code is to make the program's intent obvious, its verbosity blurs the intent of the code.

In fact, if we want to make it appear we are flattening the collection, we can also do it as follows:

foreach (var documentField in documentFields) foreach (var option in documentField.Options)
{
    option.DocumentField = documentField;
}


If we look at the two for loops as projecting a table with two columns, the projected options will now look like flattened rows.

We just have to tilt our perspective sometimes :)


Disclaimer: I won't use the last code.

Thursday, March 10, 2016

Sometimes longer code is ok

This code even it's longer..

.Select(permission => (Common.Security.PermissionEnum) System.Enum.Parse(typeof(Common.Security.PermissionEnum), permission.Value));

..is superior to this short code:

.Select(permission => (Common.Security.PermissionEnum) int.Parse(permission.Value));


The first code, even if the enum is updated to long data type, will still work.


How often do we upgrade the enum to long though?


Happy Coding!

Thursday, February 25, 2016

Unintended NHibernate Update

I encountered a strange error wherein NHibernate UPDATE an entity even I'm just selecting it from Linq.

The nature of the problem is similar to this stackoverflow question: http://stackoverflow.com/questions/2001297/nhibernate-doing-updates-on-select/2001389#2001389


Though it's similar, it befuddled me for a while as I thought there's a flaw on my implementation of custom Jsonb .NET type for Postgresql.

I tried commenting all properties that uses Jsonb type, still there's an UPDATE when just selecting an entity.

When I'm down to few properties and commented them, the DateTime type, the unintended UPDATE error is gone.

The error is in the default value of non-null DateTime, if it's not explicitly assigned, the default value is 0001-01-01, so that's what gets saved to the database. That makes NHibernate wonky when reading the entity again, the pushed value to DateTime type and the read value become different.

The timestamp column is not nullable and have a default value of CURRENT_TIMESTAMP, so I thought it's prudent to make the corresponding property on application (.NET) a not nullable type too. There's a problem with making the .NET type non-nullable, if the value is forgotten to be explicitly assigned a value (e.g., DateTime.Now) in the application, the value that will get saved to database is 0001-01-01 since it's the default value of DateTime when it's not assigned a value.


To conclude, it's better to make the .NET DateTime type nullable even if the underlying datetime type is not nullable, so when it's forgotten to be assigned a value, what will be saved to database will be null, and since the timestamp column in the table is not nullable, it will throw an exception, it will fail fast, early error, early fix, no corrupt data.


Happy Coding!

Wednesday, February 10, 2016

Cannot Load Visual Studio Project

Error:

The Web Application Project SomethingGood.Api is configured to use IIS. The Web server 'http://www.localhost.com/api' could not be found.


One possible cause of this error is when you configured your IIS 10 to accept wildcard in host name, think subdomain, or multi-tenant website. To fix it, do Unload Project, then edit the csproj, then change the IISUrl to something like this:

<IISUrl>http://*.localhost.com/api</IISUrl>

Thursday, January 28, 2016

Aggregate

There are only four domain aggregates here, can you spot them?


Here are they:


An Aggregate works as one unit, its parts should be as close together as possible.



Happy Coding!