Унифицированный уровень доступа к данным для MongoDB и SQL Server - PullRequest
4 голосов
/ 18 марта 2012

Наш проект ASP.NET MVC использует MS SQL Server (для большей части данных) и MongoDB (наименее важные вещи, такие как журналы аудита, внутреннюю систему обмена сообщениями, уведомления и т. Д.) Одновременно.Итак, вопрос в том, как должна выглядеть архитектура уровня доступа к данным в моем случае?Мы используем генератор POCO Entity Framework для доступа к SQL Server, поскольку модульное тестирование важно, и в идеале я бы предпочел расширить интерфейс IEntities, сгенерированный Entity Framework, чтобы разработчики бизнес-логики и пользовательского интерфейса даже не знали, где хранится фактический объект:

[GeneratedCode("Entity","0.9")]
public partial interface IEntities
{
    IObjectSet<Administrator> Administrators { get; }
    IObjectSet<User> Users { get; }
    IObjectSet<Banner> Banners { get; }
    IObjectSet<AuditLog> AuditLogs { get; }

    ...
}

В этом примере в MongoDB хранятся только объекты AuditLog, а остальные работают через SQL Server.

Лучшее решение, которое у меня есть, - реализовать IObjectSet интерфейс поверх драйвера MongoDB C # с MongoRepository (проект http://mongorepository.codeplex.com/) наполовину готов для решения моей проблемы. Кто-нибудь знает лучший подход?

1 Ответ

5 голосов
/ 03 июня 2012

Проблема с MongoRepository заключается в том, что ваши сущности должны быть производными от его базового класса Entity или реализовывать IEntity в каждом POCO. Я работаю над сольным проектом, который я назвал "MongoDB.Dynamic", который будет совместим с классами инфраструктуры сущностей POCO. С MongoDB.Dynamic позволит вам использовать только интерфейсы для сохранения данных.

[TestInitialize]
public void Initialize()
{
    Dynamic.Config.SetKeyName<ICustomer>(c => c.Id);
    Dynamic.Config.SetKeyName<IOrder>(o => o.Id);
    Dynamic.Config.LoadCollection<ICustomer, IOrder>(customer => customer.Orders, order => order.IdCustomer);
    Dynamic.Config.LoadFK<IOrder, ICustomer>(order => order.Customer, order => order.IdCustomer);
    var customers = Dynamic.GetCollection<ICustomer>();
    var orders = Dynamic.GetCollection<IOrder>();
    customers.RemoveAll(true);
    orders.RemoveAll(true);
}

[TestMethod]
public void TestLoadOrderByCustomerAuto()
{
    var customers = Dynamic.GetCollection<ICustomer>();
    var orders = Dynamic.GetCollection<IOrder>();

    var cust = customers.New();
    cust.Name = "X";
    customers.Upsert(cust);

    var check = customers.GetFirstOrDefault();

    var o1 = orders.New();
    o1.IdCustomer = check.Id;
    orders.Upsert(o1);

    var o2 = orders.New();
    o2.IdCustomer = check.Id;
    orders.Upsert(o2);

    var verify = customers.GetFirstOrDefault();

    Assert.IsNotNull(verify.Orders);
    Assert.IsTrue(verify.Orders.Count() == 2);
}

Через пару дней я опубликую этот проект. Не могу дождаться, чтобы поделиться с сообществом.

РЕДАКТИРОВАТЬ: интерфейсы, на которые ссылается код выше:

public interface ICustomer
{
    int Id { get; set; }
    string Name { get; set; }

    IEnumerable<IOrder> Orders { get; set; }
}

public interface IOrder
{
    int Id { get; set; }
    int IdCustomer { get; set; }

    ICustomer Customer { get; set; }
}
...