使用linq按逗号分隔的列值按相关性排序数据表

时间:2010-08-31 16:12:22

标签: c# asp.net database linq

我有一个Datatable,其中包含一个名为Tags的列,Tags可以包含诸如

之类的值
row[0] = Tag1
row[1] = Tag1, Tag2
row[2] = Tag2, Tag3
row[3] = Tag1, Tag2, Tag3
row[4] = Tag4, Tag6

并且以逗号分隔

等。

我有当前文档的标签值,并运行查询以选择其中包含任何一个标签的所有其他文档。例如,让我们说当前文档标签是(Tag1,Tag2,Tag3)

所以从上面的示例行开始,所有上面的行都是从行[4]

中返回的

这是我迷失的一点,我现在想要根据与当前文档匹配的标签数量来对数据表进行排序。所以对于我到目前为止所讨论的例子,他们应该被命令

row[3] = Tag1, Tag2, Tag3
row[1] = Tag1, Tag2
row[2] = Tag2, Tag3
row[0] = Tag1

以前没有使用linq,但被告知可以这样做。

到目前为止我已经

var query = from c in dt.AsEnumerable()
                    orderby c.Field<string>("Tags").CompareTo(dr["Tags"]) ascending
                    select c;

3 个答案:

答案 0 :(得分:2)

使用intersect方法。这是一个样本

//test data
DataTable table = new DataTable();
        var column = table.Columns.Add("Tags", typeof(string));
        table.Rows.Add("Tag1");
        table.Rows.Add("Tag1,Tag2");
        table.Rows.Add("Tag2,Tag3");
        table.Rows.Add("Tag1,Tag2,Tag3");
        table.Rows.Add("Tag4,Tag6");
        string[] currentTags = new string[] { "Tag1", "Tag2", "Tag3" };

//actual code
        var a = from row in table.AsEnumerable()
                let cData = (row["Tags"] as string).Split(new char[] { ',' }).Intersect(currentTags)
                orderby cData.Count() descending
                select cData;

答案 1 :(得分:1)

我认为这样的事情符合要求。试试吧:

// Here, I construct a simple table for demonstration
var table = new DataTable();
var column = table.Columns.Add("Tags", typeof(string));
table.Rows.Add("Tag1");
table.Rows.Add("Tag1, Tag2");
table.Rows.Add("Tag2, Tag3");
table.Rows.Add("Tag1, Tag2, Tag3");
table.Rows.Add("Tag4, Tag6");

// The separator is convenient for using the string.Split override
// that strips empty results
var separator = new[] { ",", " " };

// For the demo, we'll sort by number of tags matching the third row
var current = table.Rows[2];

// This splits the string into an array for convenient processing later
var currenttags = current.Field<string>("Tags")
                         .Split(separator, StringSplitOptions.RemoveEmptyEntries);

// The query splits out each tags field into an array convenient for processing,
// counts the number of tags contained in the currenttags array,
// sorts, and then selects the entire row.
var query = from row in table.AsEnumerable()
            let tags = row.Field<string>("Tags")
                          .Split(separator, StringSplitOptions.RemoveEmptyEntries)
            let count = tags.Count(t => currenttags.Contains(t))
            orderby count descending
            select row;

答案 2 :(得分:0)

        string[] Tags = dr["Tags"].ToString().Split(new char[] { ',' });
        string SqlClause = "";

        for (int i = 0; i < Tags.Length; i++)
        {
            if (i != Tags.Length - 1)
            {
                SqlClause += "Tags LIKE '%" + Tags[i] + "%' OR ";
            }
            else
            {
                SqlClause += "Tags LIKE '%" + Tags[i] + "%'";
            }
        }

        DataTable dt = ArticleCollection(SqlClause);

        var seperator = new[] { ",", " " };
        var current = dr["Tags"].ToString();
        var currenttags = dr.Field<string>("Tags").Split(seperator, StringSplitOptions.RemoveEmptyEntries);

        DataTable query = (from row in dt.AsEnumerable()
                    let tags = row.Field<string>("Tags").Split(seperator, StringSplitOptions.RemoveEmptyEntries)
                    let count = tags.Count(t => currenttags.Contains(t))
                    orderby count descending
                    select row).CopyToDataTable();

        for (int i = 0; i < query.Rows.Count; i++)
        {
            if (query.Rows[i]["Title"].ToString() == dr["Title"].ToString())
            {
                query.Rows[i].Delete();
            }
        }

        TagsRepeater.DataSource = query;
        TagsRepeater.DataBind();

    }
}

DataTable ArticleCollection(string whereClause)
{

    DataSet ds = TreeHelper.SelectNodes("/%", false, "CriticalCare.Conclusion;CriticalCare.Literature;CriticalCare.Theory", whereClause, " ", -1, true);
    DataTable dt = new DataTable();

    if (!DataHelper.DataSourceIsEmpty(ds))
    {            
        for (int i = 0; i < ds.Tables.Count; i++)
        {
            dt.Merge(ds.Tables[i]);
        }
        return dt;
    }
    return null;
}

}

我想要做的是,如果多个文章匹配相同数量的标签,则按照与站点树中当前文档相关的顺序对它们进行排序。我会用那个linq做什么的?在同一个查询中这样做很容易吗?是不是在数据表中添加了一个计数列?