redis / redis-om-dotnet

Object mapping, and more, for Redis and .NET
MIT License
469 stars 79 forks source link

`Select` not work when `IRedisCollection` Convert To `IQueryable` #507

Open SMAH1 opened 4 days ago

SMAH1 commented 4 days ago

Hi

Sample code:

/*
 * Redis-OM: 0.7.6
 * dotnet core 8.0
 * OS Program Run: Windows 10 22H2
 * Redis Info:
 *     redis_version:7.4.1
 *     redis_git_sha1:00000000
 *     redis_git_dirty:0
 *     redis_build_id:5918102922f65a0d
 *     redis_mode:standalone
 *     os:Linux 5.15.0-124-generic x86_64
 *     arch_bits:64
 *     monotonic_clock:POSIX clock_gettime
 *     multiplexing_api:epoll
 *     atomicvar_api:c11-builtin
 *     gcc_version:11.4.0
 */

using BugRedisOM;
using Redis.OM;
using StackExchange.Redis;

/*
[Document(StorageType = StorageType.Json, Prefixes = new[] { "BugTest:DesktopStatusEventLog" }, IndexName = "bug-desktopstatuseventlog-idx")]
public class DesktopStatusEventLog
{
    [RedisIdField] public string Id { get; set; } = string.Empty;
    [Indexed] public long DateTime { get; set; }
    [Indexed] public string Desktop { get; set; }
}
*/

var redis = ConnectionMultiplexer.Connect("10.128.1.127:6389,password=p5tg3mjyQxhE");
var provider = new RedisConnectionProvider(redis);

provider.Connection.CreateIndex(typeof(DesktopStatusEventLog));

var EventLogsSet = provider.RedisCollection<DesktopStatusEventLog>();

string[] desktops = ["D1", "D2", "D3", "D4", "D5", "D6"];

if (!EventLogsSet.Any())
{
    long now = DateTimeOffset.Now.ToUnixTimeSeconds();
    long dtStart = now - 1440 * 60 - 360 * 60;
    long dtEnd = now;

    var rnd = new Random(570);
    var eventLogs = new List<DesktopStatusEventLog>();
    foreach (var item in desktops)
    {
        for (var dt = dtStart; dt < dtEnd; dt += rnd.Next(2, 100 * 60))
        {
            eventLogs.Add(
                new DesktopStatusEventLog()
                {
                    Id = Guid.NewGuid().ToString(),
                    Desktop = desktops[rnd.Next(desktops.Length)],
                    DateTime = dt
                });
        }
    }

    foreach (var item in eventLogs) { EventLogsSet.Insert(item); }
}

var names = EventLogsSet.AsQueryable().Select(x => x.Desktop).ToArray();

Erro is:

System.InvalidOperationException: 'Searches can only be performed on objects decorated with a RedisObjectDefinitionAttribute that specifies a particular index'

and StackTrace is:

at Redis.OM.Common.ExpressionTranslator.BuildQueryFromExpression(Expression expression, Type type, Expression mainBooleanExpression, Type rootType)
at Redis.OM.Searching.RedisCollectionEnumerator`1..ctor(Expression exp, IRedisConnection connection, Int32 chunkSize, RedisCollectionStateManager stateManager, Expression`1 booleanExpression, Boolean saveState, Type rootType, Type type)
at Redis.OM.Searching.RedisCollection`1.GetEnumerator()
at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
at Program.<Main>$(String[] args) in ...............:line 67

image

slorello89 commented 4 days ago

Select is an extension method of RedisCollection, when you remove it from that context you call the wrong method.