从树结构动态生成Linq查询

时间:2015-02-26 10:13:56

标签: c# linq binary-tree tree-structure

我的问题是:

我有一个公式女巫可以拿这个代币:

  • 括号
  • 数据库中的元素=> [x:y]其中x是表名,y是主键

我想要做的是生成一个Linq查询,测试给定人员在数据库中是否存在这些元素;例如:

我的公式:[x:y]和[u:v]

我要生成的Linq查询:x.Exists(a => a.StaffIdt == GivenStaffIdt&& a.Idt = y)&& u.Exists(a => a.StaffIdt == GivenStaffIdt&& a.Idt = v)

我已经有了一个algorythm,它从我这个类型的公式生成二叉树结构:

我的公式:[x:y]和[u:v]

树:

    AND / \ [x:y] [u:v]

所以,我的猜测是创建一个递归方法,可以生成这个linq查询并将参数作为树的根,这是我需要你帮助的地方!

这是我树形结构的代码:

public class FormuleNode : IFormuleElement
{
    public enum FormuleTypeNode
    {
        Et,Ou
    }

    public FormuleTypeNode Type { get; set; }
    public IFormuleElement LeftSon { get; set; }
    public IFormuleElement RightSon { get; set; }
}


public class FormuleLeaves : IFormuleElement
{
    public enum FormuleLeavesType
    {
        AptOp, Grade, Permis, Diplome
    }

    public FormuleLeavesType Type { get; set; }
    public int Idt { get; set; }
    public string Cde { get; set; }

    public FormuleLeaves(string type, string idtCde)
    {
        switch (type)
        {
            case "AptitudeOperationnelle": this.Type = FormuleFeuilleType.AptOp;
                break;
            case "Grade": this.Type = FormuleFeuilleType.Grade;
                break;
            case "Permis": this.Type = FormuleFeuilleType.Permis;
                break;
            case "Diplome": this.Type = FormuleFeuilleType.Diplome;
                break;
        }
        if (Type == FormuleFeuilleType.AptOp || Type == FormuleFeuilleType.Grade)
            this.Cde = idtCde;
        else
            this.Idt = IntHelper.TryParseDefault(idtCde, -1);
    }

}

谢谢你,抱歉英语不好。

编辑:

我使用EntityFramework来访问我的数据库,我只有4个表链接我的员工(在我的FormuleLeavesType中描述)。

这是我生成树的方法。

public static ArrayList InfixToPostFix(string formule)
    {
        formule = RemoveAll(Espace, formule);
        Stack<string> pile = new Stack<string>();
        ArrayList res = new ArrayList();
        for (int i = 0; i < formule.Length; i++)
        {
            switch (formule[i])
            {
                case '[':
                    string token = FromIndexToChar2(formule, i, CrochetDroit);
                    res.Add(token);
                    i = token.Length - 1 + i;
                    break;
                case 'o':
                case 'O':
                    while (pile.Count != 0 && (pile.Peek() == "o" || pile.Peek() == "e"))
                        res.Add(pile.Pop());
                    pile.Push("o");
                    i++;
                    break;
                case 'e':
                case 'E':
                    while (pile.Count != 0 && (pile.Peek() == "o" || pile.Peek() == "e"))
                        res.Add(pile.Pop());
                    pile.Push("e");
                    i++;
                    break;
                case '(':
                    pile.Push(ParenthGauche.ToString());
                    break;
                case ')':
                    while (pile.Count != 0 && (pile.Peek() == "o" || pile.Peek() == "e"))
                        res.Add(pile.Pop());
                    pile.Pop();
                    break;
            }
        }
        while (pile.Count != 0)
            res.Add(pile.Pop());
        return res;
    }

    public static IFormuleElement GetArbreFromFormulePostFixeTab(ArrayList formule)
    {
        Stack<IFormuleElement> stack = new Stack<IFormuleElement>();
        foreach (string token in formule)
        {
            switch (token[0])
            {
                case '[':
                    string type = FromIndexToChar(token, 1, ':');
                    string elmt = FromIndexToChar(token, type.Length + 2, ']');
                    stack.Push(new FormuleLeaves(type, elmt));
                    break;
                case 'o': 
                    stack.Push(new FormuleNode
                   {
                       Type = FormuleNode.FormuleTypeNode.Ou,
                       RightSon = stack.Pop(),
                       LeftSon = stack.Pop()
                   });
                    break;
                case 'e':
                    stack.Push(new FormuleNode
                    {
                        Type = FormuleNode.FormuleTypeNode.Et,
                        RightSon= stack.Pop(),
                        LeftSon = stack.Pop()
                    });
                    break;
            }
        }
        return stack.Pop();
    }

0 个答案:

没有答案