Try fast search NHibernate

28 July 2009

NUnitEx 1.0.4 released

NUnitEx 1.0.4 was released today (download).

Charlie Poole, NUnit’s project leader, included NUnitEx as official NUnit AddOnsunder review for possible inclusion in NUnit 3.0” (thanks Charlie) and we are looking for some response from users (the thread is here).

News

Shorten Enumerable Constraints

Some constraints now accept a params T[] so you can write more concise assertion when the expected value is know.

var ints = new[] { 1, 2, 3 };
ints.Should().Have.SameSequenceAs(1, 2, 3);
ints.Should().Have.SameValuesAs(3, 2, 1);
ints.Should().Be.SubsetOf(1, 2, 3, 4);

These new overloads was implemented extending the extensions. ;-)

Count assertion

The Count assertion can be useful in two ways:

To have a “more readable” assertion: ints.Should().Have.Count.EqualTo(3)

As chainable assertion for IEnumerable<T>: ints.Should().Contain(3).And.Not.Have.Count.LessThan(2);

Notes

Thanks to José Romaniello NUnitEx was tested on Mono.

If you have some proposal please don’t hesitate to share it.

17 July 2009

NHibernate Configuration : Cache

Part I : NHibernate Configuration

Part II : NHibernate Fluent Configuration

Part III : NHibernate Configuration through lambdas

As mentioned in the first post of the series NHibernate allow you to configure the cache of entities classes and collections outside the class mapping (outside *.hbm.xml file). More than a “option” this ability is what you should use because, in general, we are working over second-level-cache, to tune performance, after write all mappings, after have our application working and over all after write our tests. Even if in NH2.1.0 turning off the cache (cache.use_second_level_cache=false) the cache configuration, inside a class-mapping, is ignored ,the right place to configure the cache is the Configuration (or session-factory-configuration). Using the Configuration you have the entirely picture of the Cache configuration in one place, you don’t need to touch working mappings and you can have different configurations for different environments where you are using the same set of *.hbm.xml same entities-domain.

Cache configuration in NH2

You can configure the cache through the session-factory-configuration with:

<class-cache class="NameSpace.Entity"
usage="read-write" region="ARegion"/>
<
collection-cache collection="NameSpace.Entity.CollectionProperty"
usage="read-write" region="ARegion"/>

In this case you must even add all your mappings through the session-factory-configuration.

If you need to add your mappings by code you must use the cache configuration by code using methods of Configuration class.

SetCacheConcurrencyStrategy(string clazz, string concurrencyStrategy)
SetCacheConcurrencyStrategy(string clazz, string concurrencyStrategy, string region)
SetCollectionCacheConcurrencyStrategy(string collectionRole, string concurrencyStrategy)

The cache’s configuration by code, in NH2, is not strongly typed and is not so strange because, in NHibernate, entities are not strongly typed (you can have a persistent entity’s mapping even without a class nor interface).

Cache configuration in NH3.0.0

As you saw in previous posts NHibernate 3.0.0 has some new strongly-typed ways to configure the session-factory… the cache configuration is the first step involving entities mappings.

Perhaps some examples will be enough to explain how use it.

Configuration of the second-level-cache of an entity:

configure.EntityCache<Entity>(ce =>
{
ce.Strategy = EntityCacheUsage.NonStrictReadWrite;
ce.RegionName = "MyRegion";
});

Configuration of the second-level-cache of an entity and one of its collections:

configure.EntityCache<Entity>(ce =>
{
ce.Strategy = EntityCacheUsage.NonStrictReadWrite;
ce.RegionName = "MyRegion";
ce.Collection(e => e.Elements, cc =>
{
cc.RegionName = "MyCollectionRegion";
cc.Strategy = EntityCacheUsage.NonStrictReadWrite;
});
});

Configuration of the second-level-cache of a collection avoiding the cache of its owner:

configure.EntityCache<Entity>(ce =>
ce.Collection(e => e.Elements, cc =>
{
cc.RegionName = "MyCollectionRegion";
cc.Strategy = EntityCacheUsage.NonStrictReadWrite;
}));

Strongly typed Cache configuration now available.

15 July 2009

Introducción a ORM

Despues de la charla al MUG me quedó una tarea pendiente.

La presentación está disponible aquí.

Quien assistió a la charla ya sabe que hay dos errores… para quien no vino encuentrenlo (significa que están siguiendo lo que está escrito).

12 July 2009

NUnitEx 1.0.2

NUnitEx 1.0.2 was released today.

The new release is targeting NUnit2.5.1 released few days ago.

The new NUnitEx include some new fluent assertions and one extension method useful in tests.

FieldValue<T>

Allow access to a private field where a public property is not available.

[Test]
public void SelectAndUpdateStringContainCustomWhere()
{
const string customWhere = "table_name='second'";
var dialect = new MsSql2005Dialect();
var tg = new TableGenerator();
tg.Configure(NHibernateUtil.Int64,
new Dictionary<string, string> { { "where", customWhere } }, dialect);
    tg.FieldValue<string>("query").Should().Contain(customWhere);
tg.FieldValue<string>("updateSql").Should().Contain(customWhere);
}

Guess where was needed ;)

System.Type constraints
private class B {}

[Serializable]
private class D1 : B { }

private class D2 : D1 { }
var typeToTest = typeof(D1);

typeToTest.Should().Be.SubClassOf<B>();
typeToTest.Should().Be.AssignableFrom<D2>();
typeToTest.Should().Have.Attribute<SerializableAttribute>();
String Match for custom Regex
var re = new Regex("a.b", RegexOptions.Singleline | RegexOptions.IgnoreCase);
"a\nB".Should().Match(re);

Full Syntax Overview

The full syntax overview is available in the NUnitEx wiki.

Consideration

Have a look to this NUnit assertion:

Assert.That(stringToTest, Is.EqualTo("a String Value").IgnoreCase);

What kind of comparison is used ? What mean “IgnoreCase” ?

One Microsoft recommendation about string usage is:

DON'T: Use overloads for string operations that don't explicitly or implicitly specify the string comparison mechanism.

Under the cover the NUnit assertion is equivalent to :

stringToTest.ToLower().Equals("a String Value".ToLower());

As you know the ToLower method is not enough in some languages and the default assertion is obscuring it.

For this reason I prefer:

stringToTest.ToLowerInvariant().Should().Be.EqualTo("a string value");

10 July 2009

NHibernate AddIns for WPF

José Romaniello, after some blog-posts about about examples published in uNhAddIns is going to begin a new project fully integrated with all others AddIns.

The name of the new project is uNhAddIns.Wpf, some targets are described in this post. If you are interested please leave your requests in this thread.

08 July 2009

Duck Typing with NHibernate

This is a review of this old post this time implemented using anonymous types and “dynamic type”. The solution is implemented using NH2.1.0 and .NET3.5, where the DLR is not available, so there is some trick to continue working with classes instead strings.

Duck Typing or Dynamic entities will die very soon when we want make it persistent, our 20th century technology (RDBMS) can understand only Table-Column (no object graph, nothing about no scalar types… etc.) and you can imagine how much it can understand something Dynamic. Fortunately our dear persistent layer is here to fill up the differences.

The persistent mapping

First the description of how I want persist something (something = I don’t know if it will be represented with classes, interfaces or whatever).

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">

<
class entity-name="ProductLine">
<
id name="Id" type="int">
<
generator class="hilo"/>
</
id>
<
property name="Description" not-null="true" length="200" type="string"/>

<
bag name="Models" cascade="all" inverse="true">
<
key column="productId"/>
<
one-to-many class="Model"/>
</
bag>

</
class>

<
class entity-name="Model">
<
id name="Id" type="int">
<
generator class="hilo"/>
</
id>

<
property name="Name" not-null="true" length="25" type="string"/>
<
property name="Description" not-null="true" length="200" type="string"/>
<
many-to-one name="ProductLine"
column="productId"
not-null="true"
class="ProductLine"/>
</
class>

</
hibernate-mapping>

Even if in the mapping there is the tag “class” it is only to refer to absolutely abstract entity-name and the entity-name is only to reference a mapped-artifact.

The mapping is not so trivial because it represent a parent-child bidirectional relationship.

Saving Ducks

using (ISession s = sessions.OpenSession())
using (ITransaction t = s.BeginTransaction())
{
var line = new
{
Description = "High quality cars",
Models = new ArrayList(),
Pizza = "calda"
};
var ferrari = new
{
ProductLine = line,
Name = "Dino",
Description = "Ferrari Dino",
Fuel = "Gasoline"
};
var lamborghini = new
{
ProductLine = line,
Name = "Countach",
Description = "Lamborghini Countach",
Origin = "Italy"
};
line.Models.Add(ferrari);
line.Models.Add(lamborghini);

savedId = s.SaveDynamic("ProductLine", line);
t.Commit();
}

I’m creating three anonymous objects with some property described in the mapping above and others properties without a persistent representation. In the SaveDymanic I’m using the entity-name to instruct NHibernate in order to use a specific mapping.

Updating Ducks

I’m not interested to know how NHibernate save things but when I need to retrieve a persistent instance to modify it I need a way to access to each property. Waiting DLR I can represent each state with two simple interfaces:

public interface IProductLine
{
int Id { get; set; }
string Description { get; set; }
IList<IModel> Models { get; set; }
}
public interface IModel
{
int Id { get; set; }
string Name { get; set; }
string Description { get; set; }
IProductLine ProductLine { get; set; }
}

To modify the state of the saved entity

using (ISession s = sessions.OpenSession())
using (ITransaction t = s.BeginTransaction())
{
// Reload the saved dynamic entity
var entity = s.Get("ProductLine", savedId);
// Transform it to a know type
productLine = entity.AsDynamic<IProductLine>();

// Modify through know type
productLine.Description = "Quality cars";
productLine.Models.Add(
(new
{
ProductLine = entity,
Name = "Locus",
Description = "Audi Locus"
}).AsDynamic<IModel>());

t.Commit(); // Persist modification
}

and the little test of modifications

using (ISession s = sessions.OpenSession())
{
var entity = s.Get("ProductLine", savedId);
productLine = entity.AsDynamic<IProductLine>();
productLine.Description.Should().Be.EqualTo("Quality cars");
productLine.Models.Count.Should().Be.EqualTo(3);
}

Deleting

using (ISession s = sessions.OpenSession())
using (ITransaction t = s.BeginTransaction())
{
// Delete the detached dynamic entity
s.DeleteDynamic("ProductLine", productLine);
t.Commit();
}

using (ISession s = sessions.OpenSession())
{
// check entity deletation with cascade
s.Get("ProductLine", savedId).Should().Be.Null();
s.CreateQuery("from Model").List().Count.Should().Be.EqualTo(0);
}

Conclusion

NHibernating… quack quack ;-)

07 July 2009

Dynamic entities

Waiting the release of .NET4 here is a proof of concept (for real a passing test) of what you will see in NHibernate4.0.0.

<class entity-name="Model">
<
id name="Id" type="int">
<
generator class="hilo"/>
</
id>

<
property name="Name" not-null="true" length="25" type="string"/>
<
property name="Description" not-null="true" length="200" type="string"/>
<
many-to-one name="ProductLine"
column="productId"
not-null="true"
class="ProductLine"
cascade="save-update"/>
</
class>
using (ISession s = sessions.OpenSession())
using (ITransaction t = s.BeginTransaction())
{
s.SaveDynamic("Model", new
{
Name = "Locus",
Description = "Audi Locus",
ProductLine = new
{
Description = "concept car"
}
});
t.Commit();
}

using (ISession s = sessions.OpenSession())
{
s.CreateQuery("from ProductLine pl order by pl.Description").List()
.Count.Should().Be.Equals(1);
}

NHibernate… waiting the future.

UPDATE: Was tested using NH2.1.0

04 July 2009

The art to invent: MsSQL’s artists

I’m sorry if this post will sound something heavy but I’m a little bit tired.

A little review of pagination:

in Firebird: SELECT FIRST number_of_rows SKIP offset_record rest-of-sql-statement

in MySQL: SELECT rest-of-sql-statement LIMIT offset_record, number_of_rows

in PostGre: SELECT rest-of-sql-statement LIMIT number_of_rows OFFSET offset_record

in MsSQL (even MsSQL2008) the pagination was thought by an artist of abstract art of the 19th century (with all my respect for abstract artists).

Now we have two new inventions : the function CONTAINS and FREETEXT.

Another time our “artist” in action.

If you seen the syntax, which is the natural return value of both functions ? a boolean ? a bit ? no man, that it is too much easy, a boolean is something every developer have in mind and for our “artist” is too much intuitive and easy. The solution can’t be so intuitive because the concept is opposed to “abstract art”. What the developer need is something more complicated and obscure.

So, you can do something like this:

SELECT rest-of-sql-statement WHERE CONTAINS(…, …)

SELECT rest-of-sql-statement WHERE FREETEXT (…)

SELECT rest-of-sql-statement WHERE CONTAINS(…, …) AND UnitPrice > 3.00

but you can’t do something

SELECT rest-of-sql-statement WHERE CONTAINS(…, …) = :pShouldContain

Which is the type of return-value of the two functions CONTAINS and FREETEXT ?

The definition of this kind of things, given by my father, is : The art of transforming an easy thing in a difficult through an unnecessary procedure.

02 July 2009

Evolution of : Less than “Few” is GoF

Do you remember my first blog-post ?

Well… I’m something worried because somebody can take a that concept and improve its insanity.

Perhaps was insane but not so much...

NHibernate Configuration through lambdas

Part I : NHibernate Configuration

Part II : NHibernate Fluent Configuration

This will be, probably, the last way, to configure the session-factory, available in NH-Core.

  var configure = new Configuration();
configure.SessionFactoryName("SomeName");
configure.Cache(c =>
{
c.UseMinimalPuts = true;
c.DefaultExpiration = 15;
c.RegionsPrefix = "xyz";
c.Provider<HashtableCacheProvider>();
c.QueryCache<StandardQueryCache>();
});
configure.CollectionTypeFactory<DefaultCollectionTypeFactory>();
configure.HqlQueryTranslator<ClassicQueryTranslatorFactory>();
configure.Proxy(p =>
{
p.Validation = false;
p.ProxyFactoryFactory<ByteCode.LinFu.ProxyFactoryFactory>();
});
configure.Mappings(m=>
{
m.DefaultCatalog = "MyCatalog";
m.DefaultSchema = "MySche";
});
configure.DataBaseIntegration(db =>
{
db.Dialect<MsSql2000Dialect>();
db.KeywordsAutoImport = Hbm2DDLKeyWords.AutoQuote;
db.Batcher<SqlClientBatchingBatcherFactory>();
db.BatchSize = 15;
db.ConnectionProvider<DebugConnectionProvider>();
db.Driver<SqlClientDriver>();
db.ConnectionReleaseMode = ConnectionReleaseMode.AfterTransaction;
db.IsolationLevel = IsolationLevel.ReadCommitted;
db.ConnectionString = "The connection string";
db.AutoCommentSql = true;
db.ExceptionConverter<SQLStateConverter>();
db.PrepareCommands = true;
db.Timeout = 10;
db.MaximumDepthOfOuterJoinFetching = 11;
db.HqlToSqlSubstitutions = "true 1, false 0, yes 'Y', no 'N'";
db.SchemaAction = SchemaAutoAction.Validate;
});


Perhaps the configuration through lambda is less fluent but more clear, easy to use and R# friendly.

Resuming

With NH3.0.0, you have five or six ways to configure the session-factory. The advantage of the two added in NH3 is that both are strongly typed. The fluent-configuration and the lambda-configuration was implemented using extensions-methods; probably we will extend the configuration to have a fashion way to integrate some other project (I’m thinking in some extensions in NHV, for example).

All available configuration-ways are allowing merge/override with the previous configuration that mean you can do something like:

var configuration = new Configuration();
configuration.Configure()
.Configure(yourNhConfPath)
.SessionFactoryName("SomeName")
.Proxy(p =>
{
p.Validation = false;
p.ProxyFactoryFactory<ByteCode.LinFu.ProxyFactoryFactory>();
})
.AddResources(assembly
.GetManifestResourceNames().Where(r=> r.StartsWith("NameSpace.Mappings")),
assembly)
.SessionFactory()
.Caching
.Through<HashtableCacheProvider>()
.PrefixingRegionsWith("xyz")
.Queries
.Through<StandardQueryCache>()
.UsingMinimalPuts()
.WithDefaultExpiration(15);

that mean:

  1. configure through app.config
  2. override/merge with a hibernate.cfg.xml file
  3. override/merge the proxy configuration with lambda
  4. add resources from a namespace in one assembly
  5. override/merge the cache with the fluent-configuration

What’s next ?

After some needed thinking, the next step is the programmatic configuration of the mapping.

01 July 2009

NHibernate Fluent Configuration

In this post you saw how use NH2.1.0 configuration in different ways. This post is about the fluent-interface based configuration of NH3.0.0 (well… perhaps it is not the final implementation but only closer to it). Another programmatic configuration based on lambda usage is coming.

Minimal

var cfg = new Configuration();
cfg.SessionFactory()
.Proxy.Through<ByteCode.LinFu.ProxyFactoryFactory>()
.Integrate
.Using<MsSql2005Dialect>()
.Connected
.Using(new SqlConnectionStringBuilder
{
DataSource = "(local)",
InitialCatalog = "nhibernate",
IntegratedSecurity = true
});
To configure the connection-string I’m using the DbConnectionStringBuilder of a specific DataProvider (in this case System.Data.SqlClient.SqlConnectionStringBuilder; your DataProvider should have its own implementation).

Pretty Complete

var cfg = new Configuration();
cfg.SessionFactory().Named("SomeName")
.Caching
.Through<HashtableCacheProvider>()
.PrefixingRegionsWith("xyz")
.Queries
.Through<StandardQueryCache>()
.UsingMinimalPuts()
.WithDefaultExpiration(15)
.GeneratingCollections
.Through<DefaultCollectionTypeFactory>()
.Proxy
.DisableValidation()
.Through<ProxyFactoryFactory>()
.ParsingHqlThrough<ClassicQueryTranslatorFactory>()
.Mapping
.UsingDefaultCatalog("MyCatalog")
.UsingDefaultSchema("MySche")
.Integrate
.Using<MsSql2000Dialect>()
.AutoQuoteKeywords()
.BatchingQueries
.Through<SqlClientBatchingBatcherFactory>()
.Each(15)
.Connected
.Through<DebugConnectionProvider>()
.By<SqlClientDriver>()
.Releasing(ConnectionReleaseMode.AfterTransaction)
.With(IsolationLevel.ReadCommitted)
.Using("The connection string")
.CreateCommands
.AutoCommentingSql()
.ConvertingExceptionsThrough<SQLStateConverter>()
.Preparing()
.WithTimeout(10)
.WithMaximumDepthOfOuterJoinFetching(11)
.WithHqlToSqlSubstitutions("true 1, false 0, yes 'Y', no 'N'")
.Schema
.Validating()
;

Reminder

Another programmatic configuration based on lambda usage is coming