private void RecreateBtn_Click( object sender, EventArgs e ) {
// Use NHibernate to delete everything from the database
using ( var sess = RemoteSessionHelper.SessionFactory.OpenSession() ) {
using ( var tran = sess.BeginTransaction() ) {
var list = sess
.QueryOver<Company>()
.List();
foreach ( var company in list ) {
sess.Delete( company );
}
tran.Commit();
}
}
// Now re-add the sample data
using ( var sess = RemoteSessionHelper.SessionFactory.OpenSession() ) {
using ( var tran = sess.BeginTransaction() ) {
var company = new Company() {
OfficialName = "Rossum Corporation",
Nickname = "Rossum",
City = "Cerritos",
State = "CA",
Country = "US"
};
//sess.Save( company );
var contact = new Contact() {
Name = "Adelle DeWitt",
Address1 = "[On File]",
City = "Los Angeles",
State = "CA",
Country = "US",
PostCode = "[On File]"
};
company.AddContact( contact );
//sess.Save( contact );
sess.Save( company );
tran.Commit();
}
}
namespace DemoData {
public interface IRowVersionedObject {
int RowVersion { get; set; }
}
}
namespace DemoData {
public interface ITimestampedObject {
DateTime Timestamp { get; set; }
}
}
namespace DemoData.Domain {
public class Company : ITimestampedObject, IRowVersionedObject {
//--------------------------------------
#region Properties
//--------------------------------------
public virtual Guid CompanyId { get; protected set; }
public virtual string OfficialName { get; set; }
public virtual string City { get; set; }
public virtual string State { get; set; }
public virtual string Country { get; set; }
public virtual string Nickname { get; set; }
public virtual ISet<Contact> Contacts { get; protected set; }
public virtual ISet<Tag> Tags { get; protected set; }
public virtual DateTime Timestamp { get; set; }
public virtual int RowVersion { get; set; }
#endregion Properties
//--------------------------------------
#region Public Methods
//--------------------------------------
public Company() {
Contacts = new HashedSet<Contact>();
Tags = new HashedSet<Tag>();
}
public virtual Company AddContact( Contact contact ) {
contact.SetCompany( this );
return this;
}
public virtual Company AssociateTo( Tag tag ) {
tag.AssociateTo( this );
return this;
}
public override string ToString() {
return string.Format( "{0} ({1})", OfficialName, CompanyId );
}
#endregion Public Methods
}
}
namespace DemoData.Domain {
public class Contact : ITimestampedObject, IRowVersionedObject {
//--------------------------------------
#region Properties
//--------------------------------------
public virtual Guid ContactId { get; protected set; }
public virtual Company Company { get; set; }
public virtual string Name { get; set; }
public virtual string Address1 { get; set; }
public virtual string Address2 { get; set; }
public virtual string City { get; set; }
public virtual string State { get; set; }
public virtual string PostCode { get; set; }
public virtual string Country { get; set; }
public virtual ISet<Tag> Tags { get; protected set; }
public virtual DateTime Timestamp { get; set; }
public virtual int RowVersion { get; set; }
#endregion Properties
//--------------------------------------
#region Public Methods
//--------------------------------------
public Contact() {
Tags = new HashedSet<Tag>();
}
public virtual Contact SetCompany( Company company ) {
company.Contacts.Add( this );
this.Company = company;
return this;
}
public virtual Contact AssociateTo( Tag tag ) {
tag.AssociateTo( this );
return this;
}
public override string ToString() {
return string.Format( "{0} ({1})", Name, ContactId );
}
#endregion Public Methods
}
}
namespace DemoData.MySql.Mapping {
static public class Helpers {
/// <summary>
/// Map RowVersion consistently for concurrency versioning.
/// </summary>
/// <remarks>
/// The field is named oddly to avoid using a keyword as its name.
/// </remarks>
static public void MapRowVersion<T>( ClassMap<T> mapping ) where T : IRowVersionedObject {
mapping.Version( x => x.RowVersion )
.Column( "RowVer" )
.Generated
.Always()
.UnsavedValue( "null" );
}
/// <summary>
/// Map Timestamp to colmn "TmStamp" for reconciliation timestamping
/// </summary>
/// <remarks>
/// The field is named oddly to avoid using a keyword as its name, and to avoid
/// reference to the sql type "timestamp," which we don't want to use at all
/// </remarks>
static public void MapTimestamp<T>( ClassMap<T> mapping ) where T : ITimestampedObject {
mapping.Map( x => x.Timestamp )
.Column( "TmStamp" )
.CustomSqlType( "DATETIME" );
}
}
}
namespace DemoData.MySql.Mapping {
public class CompanyMap : ClassMap<Company> {
public CompanyMap() {
Table( COMPANY_TABLE_NAME );
Id( x => x.CompanyId );
Map( x => x.OfficialName ).Length( Globals.GENERAL_NAME_LENGTH ).Not.Nullable();
Map( x => x.City ).Length( Globals.GENERAL_NAME_LENGTH ).Not.Nullable();
Map( x => x.State ).Length( Globals.STATE_LENGTH ).Nullable();
Map( x => x.Country ).Length( Globals.COUNTRY_LENGTH ).Not.Nullable();
Map( x => x.Nickname ).Length( Globals.GENERAL_NAME_LENGTH ).Not.Nullable();
HasMany( x => x.Contacts )
.Inverse()
.Cascade.AllDeleteOrphan();
HasManyToMany( x => x.Tags )
.Table( TagMap.COMPANY_TAG_TABLE_NAME )
.ParentKeyColumn( "CompanyId" )
.ChildKeyColumn( "TagId" )
.Cascade.All();
Helpers.MapTimestamp<Company>( this );
Helpers.MapRowVersion<Company>( this );
}
// To prevent compatability problems, use lowercase table names on all platforms
// MySQL options file setting: lower_case_table_names = 1
public const string COMPANY_TABLE_NAME = "company";
}
}
namespace DemoData.MySql.Mapping {
public class ContactMap : ClassMap<Contact> {
public ContactMap() {
Table( CONTACT_TABLE_NAME );
Id( x => x.ContactId );
References( x => x.Company ).Not.Nullable();
Map( x => x.Name ).Length( Globals.GENERAL_NAME_LENGTH ).Not.Nullable();
Map( x => x.Address1 ).Length( Globals.GENERAL_NAME_LENGTH ).Not.Nullable();
Map( x => x.Address2 ).Length( Globals.GENERAL_NAME_LENGTH ).Nullable();
Map( x => x.City ).Length( Globals.GENERAL_NAME_LENGTH ).Not.Nullable();
Map( x => x.State ).Length( Globals.STATE_LENGTH ).Nullable();
Map( x => x.PostCode ).Length( Globals.POST_CODE_LENGTH ).Nullable();
Map( x => x.Country ).Length( Globals.COUNTRY_LENGTH ).Not.Nullable();
HasManyToMany( x => x.Tags )
.Table( TagMap.CONTACT_TAG_TABLE_NAME )
.ParentKeyColumn( "ContactId" )
.ChildKeyColumn( "TagId" )
.Cascade.All();
Helpers.MapTimestamp<Contact>( this );
Helpers.MapRowVersion<Contact>( this );
}
// To prevent compatability problems, use lowercase table names on all platforms
// MySQL options file setting: lower_case_table_names = 1
public const string CONTACT_TABLE_NAME = "contact";
}
}
namespace DemoData.MySql {
public class MyForeignKeyConvention : ForeignKeyConvention {
protected override string GetKeyName( Member property, Type type ) {
if ( property == null ) {
return type.Name + "Id";
}
return property.Name + "Id";
}
}
}
namespace DemoData.MySql {
/// <summary>
/// This convention changes how the primary keys are named in the database
/// and how NHibernate creates them.
/// </summary>
public class MyIdConvention : IIdConvention {
public void Apply( IIdentityInstance instance ) {
instance.GeneratedBy.GuidComb();
instance.Column( instance.EntityType.Name + "Id" );
}
}
}
Some remarks:
1) you don't need two Save calls if you configure cascading from one entity's property to the other entity (company to contact); try "all";
2) the way you are deleting objects is vary bad, in performance terms; see, for example, http://weblogs.asp.net/ricardoperes/deleting-entities-in-nhibernate;
3) if you don't need GuidComb (and I guess not) you can use other Guid flavors for a slight performance improvement - GuidComb ids are ordered temporally.
RP
RP
--
You received this message because you are subscribed to the Google Groups "nhusers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nhusers+u...@googlegroups.com.
To post to this group, send email to nhu...@googlegroups.com.
Visit this group at http://groups.google.com/group/nhusers.
For more options, visit https://groups.google.com/d/optout.
RP
Hi, Charles!
I apologize, I didn’t see your mappings
because Google Groups was hiding part of the message - I had to click a "show trimmed message" link that I hadn't noticed.
Don't see anything obvious. Perhaps some other community member who is more skilled than I have can help. I'll have a look anyway and will let you know.
RP
static public void MapRowVersion<T>( ClassMap<T> mapping ) where T : IRowVersionedObject {
mapping.Version( x => x.RowVersion )
.Column( "RowVer" )
.UnsavedValue( "0" )
.Generated.Always();
}
static public void MapTimestamp<T>( ClassMap<T> mapping ) where T : ITimestampedObject {
mapping.Map( x => x.Timestamp )
.Column( "TmStamp" )
.CustomSqlType( "DATETIME" )
.Generated.Always();
}
using ( var sess = RemoteSessionHelper.OpenSession() ) {
using ( var tran = sess.BeginTransaction() ) {
var evil = new Tag() { Text = "evil" };
var company = new Company() {
OfficialName = "Rossum Corporation",
Nickname = "Rossum",
City = "Cerritos",
State = "CA",
Country = "US"
};
company.Tags.Add( evil );
company.Tags.Add( new Tag() { Text = "scientific" } );
company.Tags.Add( new Tag() { Text = "conglomerate" } );
var contact = new Contact() {
Name = "Adelle DeWitt",
Address1 = "[On File]",
City = "Los Angeles",
State = "CA",
Country = "US",
PostCode = "[On File]"
};
contact.Tags.Add( evil );
contact.Tags.Add( new Tag() { Text = "miss-lonely-heart" } );
company.AddContact( contact );
sess.Save( company );
tran.Commit();
}
}
--
You received this message because you are subscribed to a topic in the Google Groups "nhusers" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/nhusers/H1693w-OFE0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to nhusers+u...@googlegroups.com.