Почему я не могу заставить этот общий репозиторий работать?Что не так? - PullRequest
1 голос
/ 12 января 2012

У меня есть этот общий репозиторий.

 /// <summary>
/// Implémentation de base d'un dépositoire pour Entity Framework.
/// </summary>
/// <remarks>Entity Framework 4.1</remarks>
/// <typeparam name="TEntite">Entité spécifique.</typeparam>
public abstract class RepositoryBase<TEntity, TKey> : IRepository<TEntity>, IDisposable
    where TEntity : EntityBase<TKey>
    where TKey : class
{
    private readonly IContext _context;
    private ObjectContext _objectContext;
    private IObjectSet<TEntity> _objectSet;

    protected RepositoryBase(IContext context)
    {
        _context = context;
        _objectContext = _context.GetObjectContext();
        _objectSet = _objectContext.CreateObjectSet<TEntity>();
    }

    /// <see cref="IRepository.cs"/>
    public IEnumerable<TEntity> GetAll(Expression<Func<TEntity, object>> sortExpression)
    {
        if (sortExpression == null)
            sortExpression = x => x.Id;
        return _objectSet.OrderBy(sortExpression).AsEnumerable();
    }

    /// <see cref="IRepository.cs"/>
    public IEnumerable<TEntity> GetAll(int maximumRows, int startRowIndex, Expression<Func<TEntity, object>> sortExpression)
    {
        if (sortExpression == null)
            sortExpression = x => x.Id;
        return _objectSet.OrderBy(sortExpression).Skip(startRowIndex).Take(maximumRows).AsEnumerable();
    }

    /// <see cref="IRepository.cs"/>
    public TEntity SelectByKey(TKey key) 
    {
        if (key == null)
            throw new ArgumentNullException("La clé était NULL! Une clé est nécessaire pour récupérer un entité.");
        return _objectSet.SingleOrDefault(x => x.Id == key);
    }

Здесь конкретная реализация ...

public class ProductRepository : RepositoryBase<Product, int>, IProductRepository
{
    public ProductRepository(IContext context)
        : base(context)
    { }
    /// <see cref="IProductRepository.cs"/>
    public Product GetByName(string name)
    {
        return base.First(x => x.Name == name);
    }

    /// <see cref="IProductRepository.cs"/>
    public IEnumerable<Product> FindProduct(Specification<Product> specification)
    {
        throw new System.NotImplementedException();
    }
}

Когда я создаю конкретный репозиторий.это говорит о том, что Tkey должен быть ссылочным типом, но почему?Есть ли способ заставить этот общий репозиторий работать?TKey использовался для того, чтобы метод SelectByKey принимал тип ключа.

Edit # 1:

Если я уберу ограничение, у меня возникнет другая проблема ...TKey нельзя сравнивать с TKey, используя == как лямбда-выражение в моем методе SelectByKey.

Edit # 2:

Пытался использовать Equals, и синтаксис вроде бы в порядке.

Edit # 3:

Эквалайз равно во время выполнения .. говоря, что Tkey (который выглядит как System.Object) не может использовать equals, что не выглядит логикойпоскольку объект имеет равный метод.В настоящее время у меня нет доступа к реальному коду, но я провел несколько тестов с этим кодом ниже ..

class Program
{
    static void Main(string[] args)
    {
        Test<TestEntity, int> t = new Test<TestEntity, int>();  
        t.TestMethod(5);
    }
}

class Test<TEntity, TKey>
    where TEntity : Entity<TKey>
{
    public Test()
    { }

    public TestEntity TestMethod(TKey id)
    {
        List<TestEntity> testEntity = new List<TestEntity>();
        testEntity.Add(new TestEntity(5));
        return testEntity.SingleOrDefault(x => x.Id.Equals(id));
    }
}

class Entity<TKey>
{
    public TKey Id { get; set; }
}

class TestEntity : Entity
{
    public TestEntity(int id)
    {
        Id = id;
    }
}

class Entity : Entity<int>
{
}

И, похоже, он работает довольно хорошо.Поэтому я попробую позже сегодня вечером.

Edit # 4

Хорошо, исключение, которое я получаю, - Canoot создает постоянное значение типа "System.Object".В этом контексте поддерживаются только основные типы, такие как int32, string и guid.

Ответы [ 4 ]

2 голосов
/ 12 января 2012

В объявлении вашего репозитория

public abstract class RepositoryBase<TEntity, TKey> : IRepository<TEntity>, IDisposable
    where TEntity : EntityBase<TKey>
    where TKey : class
{

вы указали ограничение класса, которое допускает только ссылочные типы.См.

http://msdn.microsoft.com/en-us/library/d5x73970%28v=vs.80%29.aspx

, где T: class

Аргумент типа должен быть ссылочным типом, включая любой класс, интерфейс, делегат или тип массива.(См. Примечание ниже.)

Снимите ограничение: class, чтобы разрешить любой тип.

Если вы не участвуете в учебном упражнении, я не буду пытаться создать ваш репозиторий изцарапина.Я бы использовал то, что сделали другие.Когда я писал каркас репозитория, я хотел метод GetById, который работал бы с первичными ключами разных типов (но не с первичными ключами нескольких столбцов).При написании этого я нашел следующие два сообщения особенно полезными:

C # LINQ to SQL: Рефакторинг этого общего метода GetByID

http://goneale.com/2009/07/27/linq-to-sql-generic-repository/

0 голосов
/ 01 июня 2016

Если вы посмотрите на метаданные guid или int с помощью клавиши f12, вы увидите, что она реализует:

public struct int: IFormatable, IComparable, IComparable<int>, IEquatable<int> 
public struct Guid: IFormatable, IComparable, IComparable<Guid>, IEquatable<Guid>

тогда ограничение будет:

public interface IRepository<TEntity, TKey> 
  where TEntity: class, IEntity<TKey>
  where TKey: struct, IFormatable, IComparable, IComparable<TKey>, IEquatable<TKey>

и интерфейс IEntity должен быть таким:

public interface IEntity<TKey> where TKey: struct, IFormatable, 
                               IComparable, IComparable<TKey>, IEquatable<TKey>

но оператор == все еще не работает для меня, но метод Equals работает, как мы и ожидаем, все еще ища решение для оператора равенства.

0 голосов
/ 27 мая 2014

Добавление

where TKey : IEquatable<TKey>

Следует устранить проблему и разрешить использование синтаксиса Equals.

0 голосов
/ 12 января 2012

это говорит о том, что Tkey должен быть ссылочным типом, но почему?

У вас есть ограничение:

where TKey : class

Вам нужно ограничение? Какие типы ключей вы хотите поддерживать?

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