mirror of
				https://github.com/zoriya/Kyoo.git
				synced 2025-11-03 19:17:16 -05:00 
			
		
		
		
	Creating an expression rewritter that work with members
This commit is contained in:
		
							parent
							
								
									8430f0f1d8
								
							
						
					
					
						commit
						fb14eb4ef2
					
				@ -30,7 +30,7 @@ namespace Kyoo.Controllers
 | 
			
		||||
		
 | 
			
		||||
		public Sort(Expression<Func<T, object>> key, bool descendant = false)
 | 
			
		||||
		{
 | 
			
		||||
			Key = key;
 | 
			
		||||
			Key = ExpressionRewrite.Rewrite<Func<T, object>>(key);
 | 
			
		||||
			Descendant = descendant;
 | 
			
		||||
			
 | 
			
		||||
			if (Key == null || 
 | 
			
		||||
@ -58,6 +58,7 @@ namespace Kyoo.Controllers
 | 
			
		||||
			Key = property.Type.IsValueType
 | 
			
		||||
				? Expression.Lambda<Func<T, object>>(Expression.Convert(property, typeof(object)), param)
 | 
			
		||||
				: Expression.Lambda<Func<T, object>>(property, param);
 | 
			
		||||
			Key = ExpressionRewrite.Rewrite<Func<T, object>>(Key);
 | 
			
		||||
					
 | 
			
		||||
			Descendant = order switch
 | 
			
		||||
			{
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										46
									
								
								Kyoo.Common/ExpressionRewrite.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								Kyoo.Common/ExpressionRewrite.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,46 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Linq.Expressions;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
 | 
			
		||||
namespace Kyoo
 | 
			
		||||
{
 | 
			
		||||
	public class ExpressionRewriteAttribute : Attribute
 | 
			
		||||
	{
 | 
			
		||||
		public string Link { get; }
 | 
			
		||||
		public string Inner { get; }
 | 
			
		||||
 | 
			
		||||
		public ExpressionRewriteAttribute(string link, string inner = null)
 | 
			
		||||
		{
 | 
			
		||||
			Link = link;
 | 
			
		||||
			Inner = inner;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public class ExpressionRewrite : ExpressionVisitor
 | 
			
		||||
	{
 | 
			
		||||
		public static Expression Rewrite(Expression expression)
 | 
			
		||||
		{
 | 
			
		||||
			return new ExpressionRewrite().Visit(expression);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public static Expression<T> Rewrite<T>(Expression expression) where T : Delegate
 | 
			
		||||
		{
 | 
			
		||||
			return (Expression<T>)new ExpressionRewrite().Visit(expression);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		protected override Expression VisitMember(MemberExpression node)
 | 
			
		||||
		{
 | 
			
		||||
			ExpressionRewriteAttribute attr = node.Member.GetCustomAttribute<ExpressionRewriteAttribute>();
 | 
			
		||||
			if (attr == null)
 | 
			
		||||
				return base.VisitMember(node);
 | 
			
		||||
			
 | 
			
		||||
			Expression property = node.Expression;
 | 
			
		||||
			foreach (string child in attr.Link.Split('.'))
 | 
			
		||||
				property = Expression.Property(property, child);
 | 
			
		||||
			
 | 
			
		||||
			if (property is MemberExpression member)
 | 
			
		||||
				Visit(member.Expression);
 | 
			
		||||
			return property;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -11,12 +11,14 @@ namespace Kyoo.Models
 | 
			
		||||
		[JsonIgnore] public int PeopleID { get; set; }
 | 
			
		||||
		[JsonIgnore] public virtual People People { get; set; }
 | 
			
		||||
		
 | 
			
		||||
		[ExpressionRewrite(nameof(People) + "." + nameof(Models.People.Slug))]
 | 
			
		||||
		public string Slug
 | 
			
		||||
		{
 | 
			
		||||
			get => People.Slug;
 | 
			
		||||
			set => People.Slug = value;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		[ExpressionRewrite(nameof(People) + "."+ nameof(Models.People.Name))]
 | 
			
		||||
		public string Name
 | 
			
		||||
		{
 | 
			
		||||
			get => People.Name;
 | 
			
		||||
 | 
			
		||||
@ -71,8 +71,9 @@ namespace Kyoo.CommonApi
 | 
			
		||||
				else
 | 
			
		||||
					expression = condition;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			return Expression.Lambda<Func<T, bool>>(expression!, param);
 | 
			
		||||
 | 
			
		||||
			expression = ExpressionRewrite.Rewrite(expression);
 | 
			
		||||
			return Expression.Lambda<Func<T, bool>>(expression, param);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static Expression ContainsResourceExpression(MemberExpression xProperty, string value)
 | 
			
		||||
 | 
			
		||||
@ -98,16 +98,6 @@ namespace Kyoo.Controllers
 | 
			
		||||
			Sort<PeopleRole> sort = default, 
 | 
			
		||||
			Pagination limit = default)
 | 
			
		||||
		{
 | 
			
		||||
			if (sort.Key?.Body is MemberExpression member)
 | 
			
		||||
			{
 | 
			
		||||
				sort.Key = member.Member.Name switch
 | 
			
		||||
				{
 | 
			
		||||
					"Name" => x => x.People.Name,
 | 
			
		||||
					"Slug" => x => x.People.Slug,
 | 
			
		||||
					_ => sort.Key
 | 
			
		||||
				};
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			ICollection<PeopleRole> people = await ApplyFilters(_database.PeopleRoles.Where(x => x.ShowID == showID),
 | 
			
		||||
				id => _database.PeopleRoles.FirstOrDefaultAsync(x => x.ID == id),
 | 
			
		||||
				x => x.People.Name,
 | 
			
		||||
@ -124,16 +114,6 @@ namespace Kyoo.Controllers
 | 
			
		||||
			Sort<PeopleRole> sort = default, 
 | 
			
		||||
			Pagination limit = default)
 | 
			
		||||
		{
 | 
			
		||||
			if (sort.Key?.Body is MemberExpression member)
 | 
			
		||||
			{
 | 
			
		||||
				sort.Key = member.Member.Name switch
 | 
			
		||||
				{
 | 
			
		||||
					"Name" => x => x.People.Name,
 | 
			
		||||
					"Slug" => x => x.People.Slug,
 | 
			
		||||
					_ => sort.Key
 | 
			
		||||
				};
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			ICollection<PeopleRole> people = await ApplyFilters(_database.PeopleRoles.Where(x => x.Show.Slug == showSlug),
 | 
			
		||||
				id => _database.PeopleRoles.FirstOrDefaultAsync(x => x.ID == id),
 | 
			
		||||
				x => x.People.Name,
 | 
			
		||||
 | 
			
		||||
@ -15,7 +15,9 @@ namespace Kyoo.Models
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		[JsonIgnore] [NotMergable] public virtual IEnumerable<LibraryLink> LibraryLinks { get; set; }
 | 
			
		||||
		/*[ExpressionRewrite(x => x.LibraryLinks, y => y.Genre)]*/ public override IEnumerable<Library> Libraries
 | 
			
		||||
		
 | 
			
		||||
		[ExpressionRewrite(nameof(LibraryLinks), nameof(GenreLink.Genre))]
 | 
			
		||||
		public override IEnumerable<Library> Libraries
 | 
			
		||||
		{
 | 
			
		||||
			get => LibraryLinks?.Select(x => x.Library);
 | 
			
		||||
			set => LibraryLinks = value?.Select(x => new LibraryLink(x, this));
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user