DataAnnotations

Developer
Apr 28, 2011 at 7:17 AM
Edited Apr 28, 2011 at 7:23 AM

1) Entity Framework contains a lot of assumptions (field name Id or ClassNameId are primary keys) that could be useful when building grids, because using these assumptions you wouldn't be forced to specify the primary key if one is allready present.

2) MVC model classes typically contain DataAnnotations which specify which fields are primary keys, which are required, which have displaynames etc. This could also be useful when building the grid. Have you given any thought  to that?

Coordinator
Apr 28, 2011 at 8:13 AM

Hi,

1. Implicit assumptions, in my opinion, are not a best practice, since it makes the code less clear (as more stuff happen under the hood), and is less intuitive.

When using assumptions help reduce the amount of code, I do understand and the need for some, but specifically the examples you gave dont seem that costly.

Having said that, one of the features in the upcoming release will support the use of DataAnottation attributes to help better understand your model without the need for you to re-declare them.

Developer
Apr 28, 2011 at 8:42 AM

Implicit assumptions are all over Entity Framework, but I agree that it makes thing behave magically which increases the risk of hard to find bugs.

As for the data annotations, I was successfull in adding support for DescriptionAttribute and KeyAttribute to the demo application. Seeems to work well.

The thing that really bugs me with the current implementation is that the implementation requires that you define your columns in two separate spots which will cause maintenance problems. I'm tinkering with a method where you define the columns in one location and re-use it in bot the view and the controller. I'll let you know if I get anywhere...

Coordinator
Apr 28, 2011 at 8:46 AM
Edited Apr 28, 2011 at 8:47 AM

You don't have to define the columns twice, you can (and perhaps should - performance speaking) but dont have to.

For instance, when using the LocalData feature (introduced in 1.2.0.0), you define the columns in the view alone. (in fact, using the LocalData you dont need anything in the Controller)

In standard (paged-based) scnarios, in the Controller you could pass the model as is (with the ToGridModel extension method) and the grid will simply ignore properties that were not mapped.

If you have a better design offer, I'd love to hear (feel free to email me)

Developer
Apr 28, 2011 at 9:11 AM

I was wrong, as you say, you only have to specify the list of columns in one spot, which makes me happy and I can throw out the test I was working on.

What threw me was the list of sortable columns - I thought that that was a list of columns to include when creating the JSON response.

Developer
Apr 29, 2011 at 9:22 AM

This what I changed to add support for DisplayAttribute, EditableAttribute and KeyAttribute. IsImplicitPrimaryKey is a property that's used if no column has IsPrimarKey set.

It uses AttributeHelper which I published on my blog; http://lotsacode.wordpress.com/2011/04/27/c-reflectionhelper/

 

        public GridColumnModel Add(Expression<Func<T, object>> expression)
        {
            GridColumnModel column = new GridColumnModel(expression.MemberWithoutInstance());

            DisplayAttribute display = AttributeHelper.GetMemberAttribute<T, DisplayAttribute>(expression, attr => attr.Name != null);
            if (display != null)
            {
                column.SetCaption(display.Name);
            }

            EditableAttribute editable = AttributeHelper.GetMemberAttribute<T, EditableAttribute>(expression);
            if (editable != null)
            {
                column.SetEditable(editable.AllowEdit);
            }

            column.IsImplicitPrimaryKey = AttributeHelper.HasMemberAttribute<T, KeyAttribute>(expression);

            this.Items.Add(column);
            return column;
        }

This was also changed;

private string getKeyColumnName()
        {
            foreach (GridColumnModel col in _columns)
            {
                if (col.IsPrimaryKey) return col.Name;
            }

            // ADDED BY MATTIAS
            foreach (GridColumnModel col in _columns)
            {
                if (col.IsImplicitPrimaryKey) return col.Name;
            }

            throw new Exception("Grid Renderer Failed: Please choose a column as a primary key");
        }