【问题标题】:Query Realm for objects by IDs collection按 ID 集合查询 Realm 对象
【发布时间】:2019-01-02 15:30:07
【问题描述】:

有没有办法通过 Id 的集合查找对象列表?

类似java的代码:

realm.where(Foo.class).in("id", ids).findAll();

目前我有以下代码:

public interface IKeyedEntity
{
    string Id { get; set; }
}

public class RealmServiceWrapper<T> where T: RealmObject, IKeyedEntity
{
    public List<T> Get(List<string> ids)
    {
        return _db.Realm.All<T>().Where(a => ids.Contains(a.Id)).ToList();
    }
}

但这仍然不起作用,因为 .Net Realm 不支持 ids.Contains(a.Id)

c#中是否存在.in("id", ids)方法的替代方法?

【问题讨论】:

    标签: c# realm


    【解决方案1】:

    在编写以下扩展程序后我已经解决了我的问题:

    using Realms;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;
    
    namespace ReLife.Services.RealmRelated.RealmExtensions
    {
        public static class IQueryableExtensions
        {
            public static IQueryable<T> In<T>(this IQueryable<T> source, string propertyName, List<string> objList) where T : RealmObject
            {
                var query = string.Join(" OR ", objList.Select(i => $"{propertyName} == '{i}'"));
    
                var rez = source.Filter(query);
    
                return rez;
            }
    
            public static IQueryable<T> In<T>(this IQueryable<T> source, string propertyName, List<int> objList) where T : RealmObject
            {
                var query = string.Join(" OR ", objList.Select(i => $"{propertyName} == {i}"));
    
                var rez = source.Filter(query);
    
                return rez;
            }
        }
    }
    

    这样的扩展使我能够编写以下内容:

    public IQueryable<T> Get(List<string> ids, string idPropertyName = "Id")
    {
        return _db.Realm.All<T>().In(idPropertyName,ids);
    }
    



    更复杂的方式,但工作得更快更好:

    public static class MyQueryableExtensions
    {
        public static IQueryable<T> In<T, TProp>(this IQueryable<T> source,
            Expression<Func<T, TProp>> propSelector, IEnumerable<TProp> values)
        {
            var @params = propSelector.Parameters;
            var propAcc = propSelector.Body;
            Expression body = Expression.Constant(false, typeof(bool));
            foreach (var v in values)
                body = Expression.OrElse(body,
                    Expression.Equal(propAcc,
                        Expression.Constant(v, typeof(TProp))));
            var lambda = Expression.Lambda<Func<T, bool>>(body, @params);
            return source.Where(lambda);
        }
    }
    

    使用示例:

    _db.Realm.All<T>().In((a)=>a.Id, ids);
    

    【讨论】:

    • 谢谢,这是最好的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-28
    • 2018-05-22
    • 1970-01-01
    • 1970-01-01
    • 2013-01-23
    • 1970-01-01
    相关资源
    最近更新 更多