Thursday, 24 September 2009

Configuration of generic types in Spring.Net

Whe using Spring.Net's XML configuration files defining generic types requires a non-intuitive trick or two.

1. The left bracket () must be written using XML escape syntax (i.e. <).
2. Generic type arguments can not be fully assembly qualified as the comma is used to separate generic type arguments.

A generic object definition might look like this:

<object id="myFilteredIntList" type="GenericsPlay.FilterableList&lt;int>, GenericsPlay">
    <property name="Name" value="My Integer List"/>
</object>

Note the use of &lt;.

In the case of item 2 above it is suggested you use type aliases to clarify the text:

<typeAliases>
    <alias name="GenericDictionary" type=" System.Collections.Generic.Dictionary&lt;,>" />
</typeAliases>
<object id="myGenericObject"
type="GenericsPlay.ExampleGenericObject&lt;GenericDictionary&lt;int , string>>, GenericsPlay" />

instead of:

<object id="myGenericObject"
type="GenericsPlay.ExampleGenericObject&lt;System.Collections.Generic.Dictionary&lt;int , string>>, GenericsPlay" />

Yuk.

See section 5.2.6.1 of the Spring.Net documentation for details.

Wednesday, 23 September 2009

Enabling or disabling full-text indexing

To identify full-text indexes on a server run:

SELECT 
  object_id, 
  OBJECT_NAME(OBJECT_ID) AS ObjectName, 
  is_enabled, 
  has_crawl_completed, 
  crawl_type, 
  crawl_type_desc, 
  * 
FROM sys.fulltext_indexes 

To enable an index run:

ALTER FULLTEXT INDEX ON [ObjectNameHere] ENABLE

To disable an index run:

ALTER FULLTEXT INDEX ON [ObjectNameHere] DISABLE

Note that [ObjectNameHere] should be replaced with the object name identified from the results of the first query.

Querying SQL Profiler data

If you use the SQL Server Query Profiler and log results to a table you can get some basic stats from the results with these queries:
-- Find most frequently used queries 
SELECT DISTINCT 
    cast(textdata as varchar(150)) as textdata, 
    avg(duration) as avg_duration, 
    count(duration) as Occurences 
FROM 
    [ProfilerTableNameHere] 
GROUP BY 
    Cast(textdata as VarChar(150)) 
ORDER BY 
    count(duration)desc 

-- Find most inefficient queries 
SELECT DISTINCT 
    cast(textdata as varchar(150)) as textdata, 
    avg(duration) as avg_duration, 
    count(duration) as Occurences 
FROM 
    [ProfilerTableNameHere] 
GROUP BY 
    Cast(textdata as VarChar(150)) 
ORDER BY 
    Avg(duration)desc

Identifying tables in a database

If you need to identify the tables in a database including their row counts, column counts and data size try the following SQL:

USE [DatabaseNameHere] 

CREATE TABLE #temp ( 
  table_name sysname , 
  row_count INT, 
  reserved_size VARCHAR(50), 
  data_size VARCHAR(50), 
  index_size VARCHAR(50), 
  unused_size VARCHAR(50)) 

SET NOCOUNT ON 

INSERT #temp 
EXEC sp_msforeachtable 'sp_spaceused "?"' 

SELECT 
  a.table_name, 
  a.row_count, 
  COUNT(*) AS col_count, 
  a.data_size 
FROM 
  #temp a 
INNER JOIN 
  information_schema.columns b 
ON a.table_name collate database_default 
= b.table_name collate database_default 
GROUP BY 
  a.table_name, 
  a.row_count, 
  a.data_size 
ORDER BY 
  CAST(REPLACE(a.data_size, ' KB', '') AS integer) DESC 

DROP TABLE #temp

Monday, 21 September 2009

Problems rendering partial views

Don’t forget that when calling Html.RenderPartial() use a <% %> block and not a <%= %> block. Html.RenderPartial() doesn’t return a string of HTML but outputs directly to the calling view.

Don’t forget that because you are using a <% %>block the code elements must be ended with a semi-colon:

<% Html.RenderPartial("PartialViewName"); %>

Controlling data binding with ASP.Net MVC

If you use the UpdateModel() Controller helper method to bind data you can enforce which properties are bound to prevent unwanted data manipulation. There are three methods you can employ to provide MVC with an inclusion list of the properties to be bound.

Pass in an array of strings containing the names of the properties to be bound.

string[] properties = new[]{"Property1", "Property2"}; 
UpdateModel(myModel, properties);

Add a bind attribute to the controller action.

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult MyAction( [Bind(Include="Property1, Property2")] MyModelType model ) { //... }

Add a bind attribute to your model type. Note that this can be either an inclusion or exclusion list.

[Bind(Include="Property1, Property2")] 
public partial class MyModelType { //... }

Thursday, 17 September 2009

Defining closed vs open generic types

Generic types can be open or closed. A closed generic type is defined as follows:
"A constructed generic type that has no unspecified generic type parameters, either of its own of or any enclosing types or methods. Closed generic types can be instantiated. See also: constructed generic type, generics, generic type, generic type parameter, open generic type."
Conversely an open generic type is defined as follows:
"A constructed generic type in which one or more of the generic type arguments substituted for its generic type parameters is a type parameter of an enclosing generic type or method. Open generic types cannot be instantiated. See also: closed generic type, constructed generic type, generics, generic type argument, generic type parameter."
So, IList<Person> is a closed generic type, IList<T> is an open generic type.
Thursday, 17 September 2009,