2013-05-15 2 views
2

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

public void Save<T>(T entity) where T : TEntity, IKeyId 
{ 
    if (ObjectSet.Any(r => (r as IKeyId).KeyId == entity.KeyId)) 
    { 
     Edit(entity); 
    } 
    else 
    { 
     Add(entity); 
    } 
} 

Но Linq генерирует исключение, когда я пытаюсь сделать Any(r=> (r as IKeyId).... Выражение 'TypeAs' с вводом типа 'MyProg.DAL.Appeal' и проверка типа 'Claimstrak.DAL.Interfaces.IKeyId' не поддерживается. В запросах LINQ to Entities поддерживаются только типы объектов и сложные типы.

Как правильно это написать?

+0

Ну, исключение ясно, вы не можете использовать листинг интерфейса в linq для объектов ... Теперь, чтобы найти решение, немного больше кода (чтобы понять, как и почему вы используете ObjectSet, например) было бы полезно. –

+0

Вы знаете, что EF расскажет вам, является ли объект новым, изменен или удален. – hazimdikenli

+0

Я знаю. Unforchenatly мой ключ (id) в этой таблице не является собственным идентификатором. Столбец ссылается на другую таблицу и не является личным. – user571874

ответ

1

Ну, на самом деле вам не нужно использовать ObjectSet, вы можете просто использовать DbContext для этого, гораздо более простым способом.

Бу, я бы сказал, что это нехороший шаблон для использования, чтобы вызвать Save() в репозитории. Я бы посоветовал, что вы рассматриваете .SaveSession() Контекста только после того, как все было сделано, таким образом вы можете многое сделать, чтобы совершить поездку туда и обратно в базу данных.

Итак, вы должны сделать такой метод, но не вызывать метод SaveChanges() вместо метода Save() для UpdateOrInsert() и их, после того, как все сделано, вы вызываете .Save()

но я дам examplefollowing ваш запрос (но я не рекомендую, я рекомендую вам отделить IUnitOfWork от IRepository)

Посмотрите, как код очень прост:

interface IKeyId 
    { 
     int Id { get; set; } 
    } 

    DbContext context = new YourContext(); 

    public bool Save<TEntity>(TEntity entity) where TEntity : class, IKeyId 
    { 
     return (entity.Id == 0) ? Add<TEntity>(entity) : Edit<TEntity>(entity); 
    } 

    public bool Edit<TEntity>(TEntity entity) where TEntity : class, IKeyId 
    { 
     var set = context.Set<TEntity>(); 
     set.Attach(entity); 
     return true; 
    } 

    public bool Add<TEntity>(TEntity entity) where TEntity : class, IKeyId 
    { 
     var set = context.Set<TEntity>(); 
     set.Add(entity); 
     return true; 
    } 

Я использую подобный подход IM мои репозитории, я изменил T4 (файл .tt), что ген оценивает классы POCO из моей базы данных, чтобы явно реализовать некоторые интерфейсы, которые у меня есть, такие как IAuditable, IValidatable и другие, поэтому автоматические T4 реализуют эти интерфейсы в классах.

Смежные вопросы