4

By default EF 4.2 codefirst sets the database column behind string properties to nvarchar(max).

Individually (per property) I can override this convention by specifying the [MaxLength(512)] attribute.

Is there a way of globally applying a configuration that does this? It seems that the configuration api on modelbuilder only allows for per entity overrides and that the convention api on modelbuilder only allows removes. See this question.

Community
  • 1
  • 1
JTew
  • 3,149
  • 3
  • 31
  • 39

2 Answers2

3

No there is no global configuration available. Custom conventions were removed from EF Code First in CTP phase.

Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
  • hmmm ... I'll have a look with reflector and see if there is anyway to implement a hack using a replica of the maxlength one. – JTew Nov 16 '11 at 18:21
2

I think you can do that. Just above your property in the model table add the StringLength Attribute. Just like following. (Remember you will need to include using System.ComponentModel.DataAnnotations;)

    [StringLength(160)]
    public string Title { get; set; }

Update

  • First of all, You cannot create an index on an nvarchar(MAX) column. You can use full-text indexing, but you cannot create an index on the column to improve query performance.

  • From the storage prospective there are no difference between nvarchar(max) and nvarchar(N) when N < 4000. Data is stored in row or on the Row-overflow pages when does not fit. When you use nvarchar(max) and stores more than 4000 characters (8000 bytes) SQL Server uses different method to store the data - similar to old TEXT data type - it stores in the LOB pages.

  • Performance-wise - again, for N<4000 and (max) - there is no difference. Well, technically it affects row size estimation and could introduce some issues - you can read more about it here: Optimal way for vaiable width colums

  • What can affect the performance of the system is the row size. If you have queries that SCAN table, large row size will lead to more data pages per table -> more io operations -> performance degradation. If this is the case, you can try to do the vertical partitioning and move nvarchar field to the different table.

Pankaj Upadhyay
  • 12,966
  • 24
  • 73
  • 104
  • Hi, I was looking for a global convention. – JTew Nov 16 '11 at 18:15
  • 1
    The global convention is the use of nvarchar(MAX) only. All you can do is to override it individually and that's how it should be. If you want all your string properties in the project to have a fixed length, then why not add a function or class that detects the string properties in a model class and attach the StringLenth Attribute for you – Pankaj Upadhyay Nov 16 '11 at 18:56
  • That is the default global convention, I was looking to override it and set my own for my project. nvarchar(MAX) has downsides that I don't want to impact my project should I need to optimise it at the database level in the future i.e. no indexing of nvarchar(MAX) columns. – JTew Nov 16 '11 at 19:03
  • I have updated my answer according to your concerns regarding nvarchar(MAX) – Pankaj Upadhyay Nov 17 '11 at 06:13