Создать метод расширения linq, который принимает свойство и функцию и выполняет эту функцию для этого свойства. - PullRequest
0 голосов
/ 17 октября 2019

Как видно из заголовка, я пытаюсь создать метод расширения linq, который позволяет мне запускать функцию только с одним из свойств объекта, к сожалению, я не слишком далеко продвинулся в этом, и все, что у меня есть, это (что я считаю) это оболочка метода, чтобы сделать это:

 public static IQueryable<T> ChangeProperty<T>(this IQueryable<T> source, Expression<Func<T, string>> selector, Func<T,T> method)
    {
        //Placeholder
        return Enumerable.Empty<T>().AsQueryable();
    }

Для контекста, у меня есть эта функция, которая удаляет все элементы HTML из строки:

public static string RemoveUnwantedTags(string data)
    {
        if (string.IsNullOrEmpty(data)) return string.Empty;

        var document = new HtmlDocument();
        document.LoadHtml(data);

        var acceptableTags = new string[] { "strong", "em", "u" };

        var nodes = new Queue<HtmlNode>(document.DocumentNode.SelectNodes("./*|./text()"));
        while (nodes.Count > 0)
        {
            var node = nodes.Dequeue();
            var parentNode = node.ParentNode;
            if (acceptableTags.Contains(node.Name) || node.Name == "#text") continue;
            var childNodes = node.SelectNodes("./*|./text()");

            if (childNodes != null)
            {
                foreach (var child in childNodes)
                {
                    nodes.Enqueue(child);
                    parentNode.InsertBefore(child, node);
                }
            }
            parentNode.RemoveChild(node);
        }

        var htmlFormattingTags = new [] {"&nbsp;","&tbsp;"};
        if (!htmlFormattingTags.Any(x=>document.DocumentNode.InnerText.Contains(x))) return document.DocumentNode.InnerHtml;

        var template = document.DocumentNode.InnerText;
        foreach (var tag in htmlFormattingTags)
        {
            template = template.Replace(tag, " ");
        }
        return template;
    }

IЯ собираю данные с помощью EF, и мне понадобится эта функция для 4 разных таблиц (следовательно, я хочу сделать их общими). Так что, если я скажу этот класс:

public partial class EmailTemplate : INotifyPropertyChanging, INotifyPropertyChanged
{
    private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);

    private int _ID;
    private string _tenant;
    private string _TemplateName;
    private bool _HTML;
    private string _Body;
    private string _Images;
    private string _Subject;
    private System.Nullable<bool> _SMS;
    private System.Guid _rowguid;
    private System.Nullable<int> _OverrideServer;

^^ Усеченный, потому что это EF класс

Я хочу иметь возможность сделать

dc.EmailTemplates
    .Where(x=>x.Body != null)
    .ChangeProperty(x=>x.Body, RemoveUnwantedTags)
    .ToList();

1 Ответ

0 голосов
/ 17 октября 2019

Вы можете просто позвонить t.Body = RemoveUnwantedTags(t.Body) на каждый элемент.

dc.EmailTemplates
    .Where( t => t.Body != null)
    .ToList()//Load from db
    .ForEach( t => t.Body = RemoveUnwantedTags(t.Body)) //This is done in memory, not in the database
...