пример - интерфейсы c# для начинающих




LinqToSql и абстрактные базовые классы (3)

LINQ-to-SQL имеет некоторую поддержку наследования через дискриминатор ( здесь , здесь ), но вы можете запрашивать только классы, определенные в модели LINQ, то есть сами классы данных и (что, возможно, важно для этого примера) запрос сам должен быть сформулирован с точки зрения классов данных: хотя TEntity является классом данных, он знает, что свойство здесь объявлено на базе сущности.

Одним из вариантов может быть динамическое выражение; это сами классы объявили свойство (т. е. потеряли базовый класс, но сохранили интерфейс), но это не тривиально.

Работа с выражением будет выглядеть примерно так, как показано ниже, отметив, что вы можете либо передать строку в качестве аргумента, либо получить первичный ключ через отражение (если оно отнесено):

static Expression<Func<T, bool>> BuildWhere<T>(int deviceId) {
    var id = Expression.Constant(deviceId, typeof(int));
    var arg = Expression.Parameter(typeof(T), "x");
    var prop = Expression.Property(arg, "DeviceId");
    return Expression.Lambda<Func<T, bool>>(
        Expression.Equal(prop, id), arg);
}

У меня есть некоторые объекты linq, которые наследуют что-то вроде этого:

public abstract class EntityBase { public int Identifier { get; } }

public interface IDeviceEntity { int DeviceId { get; set; } }

public abstract class DeviceEntityBase : EntityBase, IDeviceEntity
{
  public abstract int DeviceId { get; set; }
}

public partial class ActualLinqGeneratedEntity : DeviceEntityBase
{
}

В обобщенном методе я запрашиваю объекты EntityEnityBase с:

return unitOfWork.GetRepository<TEntity>().FindOne(x => x.DeviceId == evt.DeviceId);

где TEntity имеет предел, который является DeviceEntityBase. Этот запрос всегда терпит неудачу с InvalidOperationException с сообщением «Член класса DeviceEntityBase.DeviceId не отображается». Даже если я добавлю некоторую информацию о сопоставлении в абстрактный базовый класс с помощью

[Column(Storage = "_DeviceId", DbType = "Int", Name = "DeviceId", IsDbGenerated = false, UpdateCheck = UpdateCheck.Never)]

Вау, похоже, что однажды я смогу разобраться @MarcGravell!

У меня была та же проблема, затем я обнаружил этот ответ , который решил проблему для меня!

В вашем случае вы бы сказали:

return unitOfWork.GetRepository<TEntity>().Select(x => x).FindOne(x => x.DeviceId == evt.DeviceId);

и Боб - твой дядя!


Попробуйте .OfType<>() как .OfType<>() здесь https://.com/a/17734469/3936440 , он работает для меня, имея ту же самую проблему.







linq-to-sql