My New Blog
Posted: July 28, 2015 Filed under: General Leave a commentIn case anyone is wondering. I moved my blog to Medium. You can now read me at: https://medium.com/@jdp. In due course I will be moving over some of my better blog posts.
Notes On SharePoint Business Connectivity Services
Posted: May 30, 2014 Filed under: EnterprisePortal | Tags: Business Connectivity Services, Business Data Model, SharePoint, SharePoint 2010 Leave a commentThe past 2 weeks I had an opportunity to develop a solution with SharePoint 2010’s Business Connectivity Services. I found working with SharePoint BCS to be a delicate process, with a few things not behaving entirely as expected. Here’s a few quick notes to help clarify some of the things that confused me most about BCS:
1.
For each BCS Entity’s Identifier, its Specific Finder must have an equivalent In Parameter. In other words, for example, if you have 2 Identifiers, then your Specific Finder method must have 2 corresponding input arguments.
2.
All the other methods have a dependency on the Entity’s Specific Finder. If you change the fields, or their Type Descriptors, of Specific Finder’s return parameter object, then you have to update the update and create methods accordingly. The principle is explained in the “Implementing an Updater“ article on MSDN: “If there are multiple specific finders, the Updater view should be equal to, or a subset of, at least one SpecificFinder view.” I know it refers to “multiple specific finders”, but it found it to work the same whether there’s one or more specific finders.
3.
Your permissions are removed from the BCS Service Application (in Central Admin), and you get the “Access denied by Business Data Connectivity.”, when you deploy a new BCS model, after changing the methods, Type Descriptors or any other part of the model. This didn’t always seem like it happened consistently. At times, it seemed like it was removing the permission at random, even when I just updated the code of my entities or services.
4.
Make sure you activate SharePoint Server Enterprise Site Collection features for your Web Application.
5.
Whenever I modified a Creator method, and refreshed the page, I started getting strange errors on the list page, and had to recreate the List to fix it.
Playing With Gimp
Posted: March 29, 2014 Filed under: General | Tags: Art, Gimp, Graphics Design, GraphicsArt Leave a commentPlaying around with Gimp, using some awesome free ultra high quality images from gratisography.com.
Get Up and Running With SQL Server Express, Clojure, SQL Korma and Local Jars
Posted: February 17, 2013 Filed under: SoftwareDevelopment | Tags: Artifactory, Clojure, JDBC, SQL, SQL Korma, SQL Server, SQL Server Express, SQL Server Express 2008 Leave a commentJust a sweet and short little post to help others get up to speed accessing SQL Server Express 2008 with Clojure’s SQL Korma library.
Set Up SQL Server Express
I’m using SQL Server 2008 Express. To configure your DB server go to Start > All Programs > Microsoft SQL Server 2008 > Configuration Tools > SQL Server Configuration Manager. Under SQL Server Network Configuration select Protocols for SQLEXPRESS. On the panel on the right size of the screen, make sure TCP/IP is Enabled, then right click it and select Properties. Select the IP Addresses tab, and make sure you have the following settings:
- For IP Address 127.0.0.1
- Active: Yes
- Enabled: Yes
- TCP Dynamic Ports: Make sure this entry is empty.
- TCP Port: Make sure this entry is empty.
- For IPAll:
- TCP Dynamic Ports: Make sure this entry is empty.
- TCP Port: 1433
Enable SQL Server mixed mode authentication (SQL Korma doesn’t do integrated/Windows authentication). Run regedit.exe and go to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL10.SQLEXPRESS\MSSQLServer. Change the LoginMode to 2, and restart the SQL Server Express service.
Okay, so we can now create SQL accounts on SQL Server Express, so let’s enable the SA account with SQLCMD:
- sqlcmd .\SQLEXPRESS -E
- ALTER LOGIN sa ENABLE
- GO
- ALTER LOGIN sa with password=’aPassword’
- GO
- exit
Maybe you don’t want to enable the SA account, but rather create a new non-sysadmin account, as it’s a security risk to use SA for your apps. I just used it here, as it was the shortest way to get a SQL account ;-)
Load The SQL Server JDBC Driver Into a Local Artifactory Repository
Download JFrog’s Artifactory. Go to Artifactory’s bin folder and run InstallService.bat. Then launch Artifactory with artifactory.bat, and browse to http://localhost:8081/artifactory/webapp. Grab Microsoft SQL Server JDBC Driver 3.0 and load it into a local Artifactory repository with the following settings:
- GroupId: sqljdbc4
- ArtifactId: sqljdbc4
- Version: 3.0
The reason we’re using Artifactory, is that Leiningen demands that all your dependencies come from a repository somewhere. Since Microsoft’s JDBC driver isn’t available on a public repository like Clojars, is make it available from a local repository. You’re other option is to directly load it into a Maven repository, but trust me, this is time consuming and something you want to avoid.
Now add your local repository to Lein’s defproject, :repositories {“ext-release-local” “http://localhost:8081/artifactory/ext-release-local/”}. You can see I chose to load sqljdbc4.jar into the ext-release-local repository. Also add the SQL Server JDBC driver as a dependency: [sqljdbc4/sqljdbc4 “3.0”]
Make a Nice Clojure SQL Korma
And finally drop SQL Korma as a dependency into your Leiningen project, and do the rest of its configuration as specified on Git Hub: [korma “0.3.0-RC4”]. If you’re new to SQL Korma, like I am, you might think that (defentity …) will also create your database objects for you. Not so! SQL Korma doesn’t have this feature currently (version 0.3.0) – hopefully they’ll add it in future. So make sure you’re DB objects exist and that the defentity statements correctly map to them.
Sounds like a few simple steps, but I took me unnecessarily long to piece all the above together, and get to the point of accessing SQL Server Express 2008 with SQL Korma. Hopefully the above will help others to reach SQL Server and Korma Nirvana, one time!
Vietnam: A Journey Begins
Posted: May 6, 2012 Filed under: General | Tags: Da Nang, History, Hoi An, Huế, Singapore, Travel, Vietnam Leave a commentMy wife and I recently spent about 3 weeks in central Vietnam, and a few days in Singapore. As I’m absolutely hooked on history, our trip largely revolved around exploring the history of Singapore and Vietnam, and Vietnam’s in particular is vast and very colorful. Over a series of blog posts, I will be giving a personal account of the history of central Vietnam and a little bit of Singapore, that we explored during our recent holiday. As the first blog post in the series, I won’t discuss any history, rather just give a very quick overview of the things that most South Africans ask about, when we discuss our holiday in Vietnam.
From Singapore, we flew directly to Da Nang, where central Vietnam’s airport is located, then moved to Huế, and finished our holiday in Hoi An. Also keep in mind that my opinions are based on my experience in central Vietnam. The bigger cities in the far north, Hanoi and south, Ho Chi Minh, might be quite different, just like Cape Town is vastly different from Johannesburg.
Why We Chose Vietnam
It was an inspired, intuitive decision, based on the Vietnam Eyewitness Travel Guide . My only criteria for our overseas holiday, was that I’d like to visit any country with an ancient, rich and vibrant history. I think a further motivation was the exchange rate with the Rand and the fact that things are just cheaper in Vietnam (in comparison I realized South Africa isn’t such a cheap place), which made things a lot more affordable for us. I would say, on average, things are about 50% cheaper in Vietnam than in South Africa. That goes for everything from hotels to buying things at a street market. I envy how cheap a holiday in Vietnam must be for the Europeans and British.
By the way, about the Eyewitness book. It’s a wonderful little book to get inspired about the country, but don’t depend on it to get around Vietnam day-to-day. Your Swiss army knife of info, to survive in Vietnam will be the Lonely Planet’s guide on Vietnam. That book was essential to ensuring an enjoyable stay in Vietnam.
The American War in Vietnam
The first thing most people asked, is if they have yet fully recovered from the war against America. The answer to that is an unequivocal, Yes! There are absolutely no signs in any of the cities, that there has ever been a war like that in Vietnam. And I would hope so, the American war in Vietnam ended almost 40 years ago. At historic buildings and sites some signs of the war are still visible. This is hardly surprising, since these buildings are historically significant and a heritage, therefore major restorations are not really possible or allowed.
When South Africans ask me this question, I realize just how little we know about Vietnam (and the same is true of them about Africa), and that the only, outdated, knowledge South Africans have of this amazing country and people, is that which they got from western news back in the 1970s and American war movies.
Socio Economics
In short there are few rich people in Vietnam. But, there are very few people that are desperately poor. Unlike South Africa, where there is a small group of people earning a decent living, and then a massive number of people struggling to make ends meet. Something that really got my attention, was the fact that there are no informal settlements in central Vietnam. Almost everyone has a pretty little house to live in, and many even have a small holding, that they can cultivate. There are also none of those characterless, mass cloned, little matchbox houses, that the South African department of housing builds. Each little home has it’s own style. The main buildings all have the same narrow, rectangular structure, but each building has been given its own unique style by its owner. Everyone wants to sell you something, but you won’t find any beggars at the street corners.
Crime
As anyone that has spent some time with South Africans would know, we are always obsessing about crime. I’m therefore pleased to announce that Vietnam is a very safe place indeed. Safer than South Africa. We’ve heard of people’s wallets being pinched, and someone might try to scam you in a transaction at the market, but there are no armed robberies, where peoples’ expensive valuables are stolen at gun point or knife’s edge. For example, you can walk around in the street, late at night, taking pictures with your expensive camera, without fear of being robbed.
The People
The Vietnamese people seem to be a happy bunch, that’s content with life. Everyone was extremely friendly, and helpful (especially if they have something to sell you). Compared to the Singaporeans, I found the Vietnamese to let more of their emotions show. Warm, hearty laughs and smiles, frowns and even arguments in public were more frequent. Whereas the Singaporeans kept an efficient straight face most of the time. In Da Nang we even saw an older lady (I’m guessing the mother) have a massive argument with a younger lady (I’m guessing her daughter), where she later took off her sandals and started hitting the younger woman.
I got a strong sense that the average Vietnamese really doesn’t know a lot about the world outside their country’s border. From the confused expression on their faces when we answered that we’re from South Africa, it was obvious that most Vietnamese would struggle to find South Africa on a map. Most of them thought we were German (but I don’t blame them for this, I would draw the same conclusion listening to Afrikaners talking), and then some went on to tell us, after realizing that there is “Africa” in our country’s name, that we can’t be from South Africa because we are, you guessed it, white!
Twice Vietnamese were so amused to see some westerners, that they started taking photos and videos of us, right in our faces. Now that was a strange, and slightly awkward, experience.
Language
No surprises here: Vietnamese speak and write Vietnamese. However, I was expecting the English conversations to be a much bigger problem, but it turned out that most people’s English is good enough to get the job done. English of younger people from cities are actually good enough to allow a decent conversation.
You Can Also Have A Resort Holiday In Vietnam
As I’ve already mentioned, I’m completely addicted to history. So our holiday was specifically targeted at exploring, experiencing and learning about Vietnam’s history, mainly until about the 1920s (i.e. we didn’t really pay attention to the anti colonial revolution against France, and the American war in Vietnam). We visited as many historical places as we could, and often had to walk or cycle long distances in +35°C temperatures. This isn’t very comfortable, and sometimes even a little stressful to find your way, by yourself, in an unknown place. We also stayed in the heart of each city’s centre, which isn’t always the sexiest location, but it’s closest to the action.
However, if you prefer to have more of a resort type holiday, where you relax all the time and enjoy long walks on perfect white sandy beaches, then Vietnam can offer you that as well. There are a large number of modern, luxurious beach resorts to choose from, on the beach from Da Nang to Hoi An (called China Beach). So if you’re thinking of spending a holiday at a Thailand resort, maybe also check out its equivalent in Vietnam. I can highly recommend the Hoi An beachfront for those looking for a hassle free, chill holiday. Hoi An is an old town, that has been beautifully maintained and restored. So if you stay at the Hoi An beachfront, then you will get the best of both worlds – the beach resort and classic town lifestyle. Personally, I found Hoi An to be a little boring, and too much tourist focused. For example, in Hoi An’s old town, there are literally more tourists, than Vietnamese.
What An Absolutely Amazing Country
We absolutely loved Vietnam. It was one of the most profound experiences of my life. The vibrant history, people, temples, pagodas, tombs and natural beauty was unforgettable. During a three week stay we hardly scratched the surface of what Vietnam has to offer. We will definitely return in a few years (permitting finances allow it), probably to Hanoi, as that is the heart of Vietnam’s northern history.
My New Chomma, Clojure
Posted: September 15, 2011 Filed under: SoftwareDevelopment | Tags: Clojure, Functional Programming, Java, REPL 2 CommentsA few months ago I decided that it’s time to learn a new programming language that’s completely outside my normal frame of reference. After watching a video on InfoQ about the future of programming languages, I decided Clojure would make an interesting choice. I bought the Pragmatic Programmer book, and what can I say, we’ve been becoming good friends these days.
I think I’m taking to the functional programming paradigm, and like the idea of pure functions, without shared state. Even when I program C#, I tend to make heavy use of its closures like delegates, events, anonymous methods, and lambdas, using methods as data. Learning Clojure is quite a challenge if you’ve been conditioned by years of static typed, imperative programming.
A Very Basic Clojure Work Flow For Beginners
What I’ll describe here is a very basic workflow that will enable you to write some trivial Clojure apps and work through some of the examples you might find in books and on the web. Some of these tasks aren’t that clear reading the available material, as the authors usually skip to the more exciting parts of the language.
1. Get Counterclockwise for Eclipse
2. Create an executable command line script (in my case I called it repl.sh) to launch Clojure REPL (Read Evaluate Print Loop or Interactive Console) with the required libraries referenced in the class path (Clojure runs on the Java VM):
java -cp .:src:lib/JLine/jline-0_9_5.jar:lib/clojure-1.2.1.jar:lib/clojure-contrib.jar jline.ConsoleRunner clojure.main
This adds the necessary packages to the Java class path, and launches Clojure. JLine adds functionality to the Clojure REPL, like being able to press the up arrow to retrieve the previous command.
3. Compose your Clojure application by grouping related functions in the same namespaces. The first difference you’ll notice between Clojure, and an imperative language like Java or C#, is that it doesn’t have classes, only namespaces or packages. You define a namespace with the ns function:
(ns algorhythm.test.geometry.trigonometry-tests)
This tells Clojure to switch to that namespace, and if it doesn’t exist to create it, and to create all consecutive functions defined under it. To import another namespace to make its functions available you use the “(:use”:
(:use clojure.contrib.test-is algorhythm.geometry.trigonometry algorhythm.geometry.geometric-vector)
4. Start by writing some unit tests for your Clojure application. Or if you don’t do Test Driven Development (TDD), you can skip straight to 7, writing your actual implementation.
(ns algorhythm.test.geometry.trigonometry-tests
(:use clojure.contrib.test-is algorhythm.geometry.trigonometry algorhythm.geometry.geometric-vector))
(deftest find-longest-vertex-should-find-the-longest-vertex
(def triangle {:vertex-y (struct-map geometric-vertex :length 65 :link (struct-map vertex-link :angle 90 :vertex-name “vertex-x”)),
:vertex-x (struct-map geometric-vertex :length 99 :link (struct-map vertex-link :angle 20 :vertex-name “hypotenuse”)),
:hypotenuse (struct-map geometric-vertex :length 91 :link (struct-map vertex-link :vertex-name “vertex-y”))})
(is (= 99 (find-longest-vertex triangle))))
First create and switch to the namespace where we’re going to define our unit tests. Then we tell Clojure to reference the Clojure.contrib library, where Clojure’s unit test framework is located. You then declare your unit test functions, with (deftest …), and do assertions with (is …).
5. Launch Clojure’s REPL from terminal and load your unit test .clj files with (load-file …).
jacquesd@ubuntu:~> ./repl.sh
Clojure 1.2.1
user=> (load-file “source/algorhythm/test/geometry/trigonometry_tests.clj”)
6. Run all loaded unit tests on the Clojure REPL with (run-tests). They will fail.
user=> (run-tests)
7. Now, write your required functions and repeat the cycle from 5. More specifically in our example, we should be writing algorhythm.geometry.trigonometry and algorhythm.geometry.geometric-vector, that’s required by our example unit test.
Okay, that’s my 2c to help your Clojure baby steps along. Preferably you’d opt for a proper project build system, like Leinigen, instead of manually loading and executing files through the Clojure REPL. But that’s a story for another day…
Zippy Tips Working With ServiceStack, Backbone.js, jQuery & Mono-Develop on Mac
Posted: July 30, 2011 Filed under: JavaScript, Mono, SoftwareDevelopment, Web | Tags: Backbone.js, Cross Origin Resource Sharing, JavaScript, Mono, MonoDevelop, ServiceStack, XSP Leave a commentOkay, just some random nigglies I’m experiencing and sort of solved, working with ServiceStack, Backbone.js, Mono & Mono-Develop on Mac.
MonoDevelop & XSP dev web server
Not sure who else is experiencing this issue, but my MonoDevelop and XSP dev web server gets confused sometimes, after a while. I launch two projects when I click play in my project, a web service based on ServiceStack and a ASP .NET project based on Backbone.js. For some weird reason after N number of times relaunching these 2 web projects from MonoDevelop – XSP and MonoDevelop loses track of the web service’s XSP process. The problem then is that I’m unable to re-launch the web service project with a new version.
So… in terminal do “lsof -i -P | grep [port-number-of-xsp-project-website]“. This will give you the XSP process ID. Then, again in terminal, do a “sudo kill [pid]“, to kill the ghost XSP process.
Great now you can continue launching XSP from MonoDevelop.
Cross Domain/Site Scripts with jQuery & Backbone.js
Riiight, so, I was doing the whole preflight thing with jQuery $.ajax. In Firebug I could see the OPTIONS request being made and the server returning the a 200 OK, with the following headers: Access-Control-Allow-Origin and Access-Control-Allow-Methods. BUT, $.ajax never made the actual request to PUT or POST the data to my ServiceStack web service. Well, it turns out another header is required to be returned by the web server’s response to the OPTIONS request: Access-Control-Allow-Headers, with a value of Content-Type.
So when using ServiceStack make sure you set your GlobalResponseHeaders in your AppHosts Configure(…) method:
public override void Configure(Container container) { SetConfig(new EndpointHostConfig { GlobalResponseHeaders = { { "Access-Control-Allow-Origin", "*" }, // You probably want to restrict this to a specific origin { "Access-Control-Allow-Methods", "PUT, GET, POST, DELETE, OPTIONS" }, { "Access-Control-Allow-Headers", "Content-Type" } }, }); }
Saving Models In Backbone.js
When you want to update a model, make sure you call model.save({ anUpdatedProperty: newValue, anotherUpdatedProperty: newValue }), instead of just model.save(), otherwise boggerrol will happen.
When your Backbone.js app talks to a web service that serializes data into a CamelCase format, like C#’s properties, then Backbone’s collection.get(…) won’t work for you, because your model’s id property‘s name will be “Id” and not “id”. To get around this add the idAttribute to your Backbone.js Model, to reroute id to your chosen property on the model object:
var theModel = Backbone.Model.extend( { idAttribute: "Id" }); <pre>
Cool. That’s it for now. Catch you on the flip side!
Discover Dynamic Object Creation In Ruby
Posted: May 5, 2011 Filed under: Ruby | Tags: Class, const_get, Dynamic Object Creation, inject, Module, Object, Ruby Leave a commentLet me quickly explain Ruby‘s dynamic object creation. When I talk about dynamic object creation, I’m referring to when you instantiate a new object instance from meta-data using a class (also referred to a as a Type in .NET) name, or class meta-data object. In languages like C#, and Java you will use reflection to dynamically invoke objects like this. Ruby has two equivalents, depending on whether you’re invoking an object from a class’s name or a class meta-data object. Invoking an object from a class meta data object is very straight forward:
class_meta_obj = Module1::Module2::Module3::SomeClass return class_meta_obj.new
All you do to instantiate a new object instance from a class definition, is to call new on it.
Invoking an object from a class name is more cumbersome than I think is necessary, because you first need to load each module in the full class name:
class_name = "Module1::Module2::Module3::SomeClass" result_class_meta_obj = class_name.split('::').inject(Object) { |result_class_meta_obj, item| result_class_meta_obj.const_get item } return result_class_meta_obj.new
First we split the module & class hierarchy on the separator “::”. This gives us each individual module and class in an Array. For each item in the array we pass in the last result returned by the block (result_class_meta_obj), and the current module or class name (item). The argument passed to the inject method (Object) is the first iteration’s last result (result_class_meta_obj).
On the class/module meta object we send the current module/class’s name to const_get. This returns the current module/class’s meta data object, that then becomes the latest result. Each class and module name is a constant in Ruby that points to its corresponding class/module definition. Now that we have the class definition meta data object, we can invoke its constructor the same way as in the first example.
Hey NHibernate, Don’t Mess With My Enums!
Posted: April 16, 2011 Filed under: C#, DataBase, Mono.NET | Tags: .NET, C#, DataBase, Enum, Fluent NHibernate, Mono, NHibernate, ORM 2 CommentsSo I’ve been using Fluent NHibernate for a short while now. Initially I had to overcome some minor challenges, but since I got those out of the way it’s been pretty smooth sailing. One thing that stands out, which required more tinkering and timeshare than I would’ve liked is the way NHibernate handles the .NET enum type. Natively NHibernate allows you to save your enum’s value as a string or number property/column in the referencing object’s table. In other words, by default it doesn’t allow you to map your enum to its own separate table, and then let your objects refer to it through an association/foreign key. For NHibernate enums are primitive values, and not “entity objects” (logically speaking – ignoring the technical internal mechanics of .NET’s enum). I would argue that enums can be both a primitive string or number, or a more complex entity. Under certain circumstances an enum can be viewed as a simple “object” that consists of two properties:
- An Id, represented by the enum member’s number value
- And a name, represented by the enum member’s string name.
I’ve found that it’s very convenient to use the “entity object” version of enums for very simple, slow changing look-up data with a fair amount of business logic attached to it. For instance in a credit application app, you might only support 3 or 4 types of loans, but you know that over time app’s life, the company won’t add more than 2 or 3 new types of loans. Adding a loan type requires some additional work, and isn’t merely a matter of just inserting a new loan type into a look-up table. The reason is that a fair amount of the app’s business logic, mainly in the form of conditional logic statements, must also be adapted to accommodate the new loan type. From a coding perspective it’s very convenient to use enum types in these cases, because you can refer to the various options through DRY strong typed members, with a simultaneous string and number representation. So instead of
var loan = loanRepository.FindById(234); var loanType = loanTypeRepository.FindById(123); // ... if (loan.Type == "PersonalLoan") { // ... }
rather do
var loan = loanRepository.FindById(234); if (loan.Type == LoanType.Personal) { //... }
Okay, schweet, you get the point. Next logical question: How do you get NHibernate to treat your enums as objects with their own table, and not primitive values? To do this you have to create a generic class that can wrap your enum types, and then create a mapping for this enum wrapper class. I call this class Reference:
public class Reference<TEnum> { private TEnum enm; public Reference(TEnum enm) { this.enm = enm; } public Reference() {} public virtual int Id { get { return Convert.ToInt32(enm); } set { enm = (TEnum)Enum.Parse(typeof(TEnum), value.ToString(), true); } } public virtual string Name { get { return enm.ToString(); } set { enm = (TEnum)Enum.Parse(typeof(TEnum), value, true); } } public virtual TEnum Value { get { return enm; } set { enm = value; } } }
The Reference class is pretty straight forward. All it does is translate the contained enum into an object with three properties:
- Id – the integer value of the enum member.
- Name – the string name of the enum member.
- Value – the contained enum member.
You might wonder why I didn’t bother to restrict the allowed generic Types to enums. Well, it so happens that .NET generics doesn’t allow you to restrict generic type declarations to enums. It allows you to restrict generic types to structs, and all sort of other things, but not to enums. So you will never be able to get an exact generic restriction for the Reference class. So I thought, aag what the hell, if I can’t get an exact restriction, then what’s the point anyways? I’ll have to trust that whoever is using the code, knows what he’s doing.
Now, for example, instead of directly using the LoanTypes enum, the Loan class’s Type property will be a Reference object, with its generic type set to the LoanTypes enum:
public class Loan { // ... public Reference<LoanType> Type { get; set; } // ... }
This is not completely tidy, because to a degree the limitations of the data access infrastructure, i.e. NHibernate, force us to adopt a compromise solution that’s not necessary if we changed to something else. In other words things from the data infrastructure layers spills into the domain.
What’s left to do is (1) create a mapping for Reference<LoanType>, and (2) get NHibernate to use the right table name, i.e. LoanType, instead of Reference[LoanType]. Here the Fluent NHibernate mapping for Reference<LoanType>:
public class LoanTypeMap: ClassMap<Reference<LoanType>> { public LoanTypeMap() { Table(typeof(LoanType).Name); Id(loanType => loanType.Id).GeneratedBy.Assigned(); Map(loanType => loanType.Name); } }
The above Fluent NHibernate mapping tells NHibernate to use whatever value property Id has for the primary key, and not generate one for it. You also have to explicitly specify the table’s name you’d like NHibernate to use, because you want to ignore “Reference” as part of the table name, and only use the enum type name.
And that’s it. You will now have a separate table called LoanType, with the foreign keys of other classes’ tables referencing the LoanType enum’s table. Just keep in mind that this solution might not always be feasible. For example it might not work too well when you write a multilingual application. Also should you want to get a pretty description for each enum’s member, for example “Personal Loan”, instead of “PersonalLoan” you’ll have to throw in some intelligent text parsing that split’s a text string before each uppercase character. Hopefully this post gave you another option to map your enum types with NHibernate.