How to design domain with entity referencing entity on another sql server with NHibernate persistance

StackOverflow https://stackoverflow.com/questions/10958732

Вопрос

I need to design domain that has two simple entities:

public class User
{
    public virtual int Id { get; protected set; }
    public virtual string Email { get; protected set; }
    public virtual Country Country { get; protected set; }
    ...
}

public class Country
{
    public virtual int Id { get; protected set; }
    public virtual string Name { get; protected set; }
    ...
}

It's all nice and clear in domain world but the problem is that User and Country persisted in two different databases on two different servers (tho they are both MSSQL 2005 servers).

So, how should I correctly implement persistance of entites across different sql servers in NHibernate?

Using IDs instead of objects in references? Yeah, thats simple but it's hitting hard on the whole domain thing making domain object more like DTO. And it will require that IUserRepository get it's hands on ICountryRepository to load User entity.

Linked servers? Hm... Somehow I don't like it (distributed transactions and no XML columns). And what I should be aware in case of using them and more importantly how should I configure NHibernate to work effectively with linked servers?

Maybe some other solution?

Это было полезно?

Решение

I've heard of people using the schema property in a class mapping to contain the linked server name (like otherserver.dbo), but I don't know anyone that hasn't ran into one problem or another when doing that.

There are a few DDD bootstrapping frameworks that allow you to transparently map entities to different databases (resulting in multiple ISessionFactories, which it will manage for you). NCommon is one I would recommend. This assumes, however, that Country only exists in one database, and User only exists in another.

As for transactions... well, if you use a TransactionScope and configure DTS, that might work. NCommon uses a UnitOfWork API that also wraps TransactionScope.

You would have to change User so that Country is just an ID. Here's why. You'd end up with two session factories, one that has a mapping for Country and the other that has a mapping for User. If you don't make that change, NHibernate will complain that there is no mapping for Country when you save User (since they are stored in two different DBs).

Now you could instruct NHibernate to ignore Country property, and keep Country so your domain doesn't change. However, when you load User from the database next time, Country will be null.

Другие советы

You could use NHibernate.Shards from NHContrib.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top