EF Code First CTP 5: проверка сущности, которая зависит от других сущностей (например, уникальные ограничения) - PullRequest
1 голос
/ 24 марта 2011

Каковы некоторые рекомендации по обработке проверки сущностей домена, которые зависят от других сущностей домена, использующих POCO, которые создаются при реализации ORM на основе кода EF First?

Вот ситуация, в которой я пытаюсьПроработайте: у меня есть класс, который представляет клиентский компьютер, и есть свойство этого класса, которое представляет IP-адрес компьютера.Мне нужно, чтобы это было уникальным, но я не могу найти элегантное решение для обеспечения этого ограничения.В настоящее время я делаю это на сервисном уровне, где я обновляю / вставляю сущность.

- UPDATE -

Я знаю, что EF не поддерживает уникальные ограничения, и я уже добавил ограничениек таблице базы данных, но я бы предпочел поймать ограничение, прежде чем я попаду в базу данных.То, что я искал, было лучшим способом обработки проверки, который зависит от других объектов в целом и использовал в качестве примера ограничение уникальности.

- ОБНОВЛЕНИЕ 28.03.2010 -

Для справки, вот как я сейчас работаю с уникальным ограничением для IP (_unitOfWork имеет тип SqlMessageUnitOfWork: в основном он оборачивается вокруг используемого мной DBContext, предоставляя IDbSets для всех соответствующих таблиц):

public class ClientService : IClientService
{
    public ValidationResult InsertClient(ClientDTO clientDTO)
    {
        var existingClient = _unitOfWork.Clients.Where(x => x.IP == clientDTO.IP).SingleOrDefault();

        if (existingClient != null)
        {           
            return new ValidationResult("IP already in Use.", new[] { "IP" });
        }
        else
        {
            var newclient = new Client();
            ClientEntityMapper.MapToEntity(clientDTO, newclient, _unitOfWork.Terminals);
            _unitOfWork.Clients.Add(newclient);
            _unitOfWork.Commit();
        }

        return ValidationResult.Success;
    }
    ...

    private IUnitOfWork _unitOfWork;

    public ClientService(IUnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }
}

public interface IUnitOfWork
{
    IDbSet<Message> Messages { get; }
    IDbSet<Terminal> Terminals { get; }
    IDbSet<Client> Clients { get; }
    IDbSet<MessageDisplayInstance> MessageDisplayInstances { get; }
    void Commit();
}

public class SqlMessageUnitOfWork : IUnitOfWork
{
    readonly VisualPagingDbContext _context;

    public SqlMessageUnitOfWork()
    {
        _context = new VisualPagingDbContext();
    }

    public void Commit()
    {
        _context.SaveChanges();
    }

    public IDbSet<Message> Messages
    {
        get { return _context.Messages; }
    }

    public IDbSet<Terminal> Terminals
    {
        get { return _context.Terminals; }
    }

    public IDbSet<Client> Clients
    {
        get { return _context.Clients; }
    }

    public IDbSet<MessageDisplayInstance> MessageDisplayInstances
    {
        get { return _context.MessageDisplayInstances; }
    }
}

Ответы [ 3 ]

0 голосов
/ 25 марта 2011

Если вам нужно установить уникальные ограничения, вы можете сделать это, выполнив команду sql.

Поэтому, где бы вы ни настраивали модель вашего домена, вы можете добавить строку для выполнения sql.Так что в вашем случае следующее должно делать эту работу:

string script = "ALTER TABLE <table-name> ADD CONSTRAINT UniqueElement UNIQUE (<column-name>)";
context.Database.SqlCommand(script);
0 голосов
/ 14 мая 2012

Чтобы добавить проверку уникальности в мою проверку сущности, я переопределил ValidateEntity в контексте и добавил следующее:

if (entityEntry.Entity is Role &&
            (entityEntry.State == EntityState.Added || entityEntry.State == EntityState.Modified))
        {
            var role = entityEntry.Entity as Role;

            if (!string.IsNullOrEmpty(role.ShortName))
            {
                if (
                    Roles.Any(
                        p => p.ShortName.ToLower() == role.ShortName.ToLower() && !p.RoleID.Equals(role.RoleID)))
                {
                    result.ValidationErrors.Add(new DbValidationError("ShortName", "Role Short Name already exists"));
                    return result.ValidationErrors.Count > 0 ? result : base.ValidateEntity(entityEntry, items);
                }
                //Remeber to check local collection - otherwise we could end up saving two or more at once that are duplicated
                if (
                    Roles.Local.Count(p => p.ShortName.ToLower() == role.ShortName.ToLower() && !p.Equals(role)) > 0)
                {
                    result.ValidationErrors.Add(new DbValidationError("ShortName", "Role Short Name already exists"));
                    return result.ValidationErrors.Count > 0 ? result : base.ValidateEntity(entityEntry, items);
                }
            }
        }

Если вам нужно получить EF для создания ограничений / индексов и т. Д. В базе данных, пожалуйста,см .:

Код Entity Framework First Fluent Api: добавление индексов в столбцы

0 голосов
/ 24 марта 2011

EF вообще не поддерживает уникальные ограничения ( они запланированы на будущие версии ), но это не значит, что вы не можете добавить их в таблицы базы данных (например, в пользовательском инициализаторе). То, что вы описываете, это проверка, которая требует запроса к базе данных. Это проверка бизнеса, которая должна быть реализована и выполнена при необходимости. Это не то, что EF будет обрабатывать для вас. Btw. CTP5 является устаревшей версией. Используйте EF 4.1 вместо .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...