Некоторые проблемы с групповым соединением двух таблиц с помощью LinQ

#c# #linq #asp.net-core #ef-code-first #entity-framework-core

#c# #linq #asp.net-core #ef-code-first #entity-framework-core

Вопрос:

У меня есть несколько таблиц в базе данных, которые будут объединены в Log таблицу.

Вот одна из таблиц, и после этого я показал Log таблицу

Пользовательская сущность:

 public class User : BaseEntity
{
    public User()
    {
        Beneficiaries = new HashSet<Beneficiary>();
        Applicants = new HashSet<Applicant>();
        UserItemCategories = new HashSet<UserItemCategory>();
        UserPropertyCategories = new HashSet<UserPropertyCategory>();
        Payments = new HashSet<Payment>();
    }

    [Required]
    public Role Role { get; set; }

    [Required]
    public string FirstName { get; set; }

    [Required]
    public string LastName { get; set; }

    [Required]
    public string Mobile { get; set; }

    [Required]
    public string Username { get; set; }

    [Required]
    public string Phone { get; set; }

    [Required]
    public string Address { get; set; }

    [Required]
    public string Password { get; set; }

    public double FixedSalary { get; set; }
    public DateTime DateOfPay { get; set; }
    public virtual ICollection<Beneficiary> Beneficiaries { get; set; }
    public virtual ICollection<Applicant> Applicants { get; set; }
    public virtual ICollection<UserItemCategory> UserItemCategories { get; set; }
    public virtual ICollection<UserPropertyCategory> UserPropertyCategories { get; set; }
    public virtual ICollection<Payment> Payments { get; set; }
}
  

Класс BaseEntity:

 public abstract class BaseEntity
{
    public string Id { get; set; }

    public DateTime DateTime { get; set; }
}
  

Объект журнала:

 public class Log : BaseEntity
{
    public TrackTypeEnum Type { get; set; }

    [Required]
    public string CreatorId { get; set; }

    [Required]
    public string EntityId { get; set; }
}
  

В Log таблице я хотел объединить entityId с User идентификатором таблицы
я написал код, чтобы справиться с этим:

 public static IQueryable<TEntity> Filtered<TEntity>(this IQueryable<TEntity> entities, IQueryable<Log> logDbSet) where TEntity : BaseEntity
{
    var entitiesWithAttachedLogs = entities
        .GroupJoin(logDbSet, entity => entity.Id, log => log.EntityId, (entity, logs) => new
        {
            Entity = entity,
            Logs = logs
        });

    var groupedEntities = entitiesWithAttachedLogs.GroupBy(key => key.Entity.Id, value => new
    {
        value.Entity,
        Logs = value.Logs.DefaultIfEmpty()
    });

    var shrinkGroup = groupedEntities.SelectMany(group => group, (group, item) => new
    {
        TrackedEntity = item
    });

    var condition = shrinkGroup.Where(x =>
        (x.TrackedEntity.Logs == null || !x.TrackedEntity.Logs.Any())
        || (x.TrackedEntity.Logs.Any() amp;amp; x.TrackedEntity.Logs.OrderBy(c => c.DateTime).FirstOrDefault().Type != TrackTypeEnum.Delete));
    var catchEntity = condition.Select(x => x.TrackedEntity.Entity);

    return catchEntity;
}
  

Некоторые строки могут не иметь никакого статуса журнала.

Я собираюсь получить «Не удаленные» пользователи:

 var models = _users.Filtered(_logs);
var foundUser = await (from user in models
                       where user.Id == currentUser.Id
                       where user.Username == currentUser.Username
                       where user.Mobile == currentUser.Mobile
                       where user.Role == currentUser.Role
                       where user.Password == currentUser.EncryptedPassword
                       where user.FirstName == currentUser.FirstName
                       where user.LastName == currentUser.LastName
                       where user.Phone == currentUser.Phone
                       select user).FirstOrDefaultAsync().ConfigureAwait(false);
return foundUser != null; 
  

Но когда я хочу сообщить пользователям, что они не удалены (на основе Log свойства Type ), он возвращает эту ошибку:

 InvalidCastException: Unable to cast object of type 'DefaultIfEmptyAsyncIterator`1[RealEstate.Domain.Tables.Log]' to type 'System.Collections.Generic.IEnumerable`1[RealEstate.Domain.Tables.Log]'. 
  

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

Заранее спасибо.

Комментарии:

1. Очевидно, где-то тип не такой, каким вы его себе представляли. Вы использовали свой отладчик для проверки возвращаемого значения select ? это тот ввод, на который вы надеялись FirstOrDefaultAsync ? И что вы ожидали в качестве возвращаемого значения FirstOrDefaultAsync ? Вы пытались вводить все типы буквально, вместо var, и пытались ли вы делать это меньшими шагами, чтобы увидеть, с чего началась ошибка типа?

2. @HaraldCoppoolse я уже проверил все, что вы сказали, но это не сработало, и я изменил приведенные выше коды в основном в своем проекте.

3. Итак, какое возвращаемое значение Select?