EF4.1 (База данных сначала) Универсальный репозиторий: проблема с несовместимыми типами данных - PullRequest
1 голос
/ 16 мая 2011

Я работаю над новым приложением, которое использует базу данных устаревшей системы. Каждая таблица в базе данных (их около 600) имеет столбец «Удалено», чтобы указать, должен ли элемент отображаться пользователям. В моем общем хранилище мне нужно добавить выражения LINQ, чтобы отфильтровать все элементы с Deleted == 1 / True.

Проблема, с которой я столкнулся, состоит в том, что столбец «Удаленный» имеет разные типы данных в разных таблицах.

Это крошечный знак, маленький знак или бит в любой таблице. Теоретически, это не должно быть большой проблемой, так как данные всегда будут храниться как 1 или 0 (ну, должно быть, я полагаю, но так или иначе, в некотором роде), который может быть приведен к любому конкретному упомянутые выше типы. Я просто не знаю, как и / или где это делать.

Я создал интерфейс, который заставляет все объекты раскрывать это свойство, но, поскольку типы различаются, каждая сущность с различными типами данных будет вызывать проблемы. Я надеялся (хотя уже знал, что это не будет работать), я мог бы изменить интерфейс на «объект» или «динамический», что все еще вызывает ошибки времени компиляции, так как модель EDMX создает классы модели данных. Я не хочу тратить слишком много времени на написание кода в шаблонах T4, если это не решит проблему.

Когда я изменяю свойства сущности модели EDMX для привязки к определенному типу данных, я получаю ошибки сопоставления («Недопустимо конкретное сопоставление элемента. Тип« Edm.Byte [] »члена« Удалено »в типе «MyEntity» несовместимо с «SqlServer.bit []» ....)

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

Кто-нибудь еще сталкивался с подобной ситуацией и придумал рабочее решение?

[EDIT] Я собираюсь использовать решение, рекомендованное Балди, и создать представление для обтекания таблицы и создать дополнительный столбец, который будет использоваться для приведения столбца к разряду.

Ответы [ 3 ]

1 голос
/ 17 мая 2011

Возможно, вы захотите рассмотреть специальную задачу преобразования фактических полей в таблице с помощью сценария T-SQL.

Вы думали об этом?есть ли причина, по которой вы не можете это сделать?

это может оказаться хорошим шагом вперед по линии ...

1 голос
/ 17 мая 2011

Общий подход основан на том факте, что ваши сущности ведут себя одинаково.В вашем случае это означает то же свойство с тем же типом.Ваши сущности не выполняют это требование, и поэтому вы не можете использовать общий подход.

Вы должны каким-то образом ввести общее поведение.Как насчет этого:

public interface IDeletable<TVal> where TVal : struct
{
    TVal Deleted { get; set; }
}

public class Entity : IDeletable<bool>
{
    public bool Deleted { get; set; }
    ...
}

public interface IDeletingStrategy<TEntity, TVal> 
    where TEntity : class, IDeletable<TVal>
    where TVal : struct
{
    void Delete(TEntity entity);
    IQueryable<TEntity> GetActive(IQueryable<TEntity> query);
}

public class Repository<TEntity, TVal> 
    where TEntity : class, IDeletable<TVal>
    where TVal : struct
{
   private IDeletingStrategy<TEntity,TVal> _deletingStrategy;

   public Repository(IDeletingStrategy<TEntity, TVal> deletingStrategy)
   {
       _deletingStrategy = deletingStrategy;
   }

   public void Delete(TEntity entity)
   {
       _deletingStrategy.Delete(entity);
       ...
   }

   public IQueryable<TEntity> GetActive()
   {
       return _deletingStrategy.GetActive(context.Set<TEntity>());
   }

}

public class BoolDeletingStrategy<TEntity> : IDeletingStrategy<TEntity, bool>
    where TEntity : class, IDeletable<bool>
{
    public void Delete(TEntity entity)
    {
        entity.Deleted = true;
    }

    public IQueryable<TEntity> GetActive(IQueryable<TEntity> query)
    {
        return query.Where(e => !e.Deleted);
    }
}

И вы создадите экземпляр своего хранилища, например:

var repo = new Repository<Entity, bool>(new BoolDeletingStrategy<Entity>());

Я не проверял его, но, думаю, он может работать.

1 голос
/ 16 мая 2011

Можете ли вы создать собственное свойство только для чтения в каждом классе модели, используя частичные классы, которые считывают удаленный бит и возвращают равномерное и непротиворечивое значение?

...