LINQ使用system.data.sqlite生成错误的sql查询

时间:2014-06-17 12:25:18

标签: c# sql linq sqlite mono

我有以下型号:

[Table(Name="word")]
public partial class Word
{
    [Column(IsPrimaryKey=true, Name="id")]
    public int Id { get; set; }

    [Column(IsPrimaryKey=true, Name="language_id")]
    public int LanguageId { get; set; }

    [Column(Name="translation")]
    public string Translation { get; set; }

    [Column(Name="category")]
    public string Category { get; set; }

    [Column(Name="order")]
    public int Order { get; set; }
}

以下代码:

var connection = new SQLiteConnection(@"Data Source=data.sqlite3");
var context = new DataContext(connection);
context.Log = Console.Out;

var test = from w1 in context.GetTable<Word> ()
           join w2 in context.GetTable<Word> () on w1.Id equals w2.Id
           select new {w1 = w1.Id, w2 =  w2.Id};

foreach (var i in test)
{
    Console.WriteLine("Word: {0} {1}", i.w1, i.w2);
}

输出如下:

SELECT w1$.[id], w2$.[id]
FROM [word] AS w1$, [word] AS w2$
WHERE (w1$.[id] = w1$.[id])
-- Context: SqlServer Model: AttributedMetaModel Build: 4.0.0.0
Word: 1 1
Word: 1 1
Word: 1 2
Word: 1 2
Word: 1 3
Word: 1 3
Word: 1 4
Word: 1 4
Word: 1 5
Word: 1 5

发生了什么事?为什么连接条件与我指定的不同?这是一个错误还是我做错了什么?为了它的价值,我在Mac上使用Mono,我已经为他们的网站上描述的mono编译了system.data.sqlite。

更新

这种解决方法解决了这个问题:

var test = from w1 in context.GetTable<Word> ()
           join w2 in context.GetTable<Word> () on w1.Id equals w2.Id
           where w1.Id == w2.Id
           select new {w1 = w1.Id, w2 =  w2.Id};

更新2:

显然,linq 2 sql与sqlite相比非常糟糕。建议的解决方案是使用实体框架。

1 个答案:

答案 0 :(得分:0)

我认为问题在于SQLite驱动程序无法很好地处理自联接。我刚在SQLServer中尝试过同样的事情

我的表看起来像这样

Id  Language_id Translation
1   1   hello
1   2   bonjour
1   3   yo
2   1   bye
2   2   aurevoiur
2   3   laterz

并且输出看起来像这样(我添加了翻译专栏以帮助查看更容易发生的事情)

SELECT [t0].[id] AS [w1], [t0].[translation] AS [word1], [t1].[id] AS [w2], 
[t1].[translation] AS [word2]
FROM [word] AS [t0]
INNER JOIN [word] AS [t1] ON [t0].[id] = [t1].[id]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.18408

Word: 1 = hello,  1 = hello
Word: 1 = bonjour,  1 = hello
Word: 1 = yo,  1 = hello
Word: 1 = hello,  1 = bonjour
Word: 1 = bonjour,  1 = bonjour
Word: 1 = yo,  1 = bonjour
Word: 1 = hello,  1 = yo
Word: 1 = bonjour,  1 = yo
Word: 1 = yo,  1 = yo
Word: 2 = bye,  2 = bye
Word: 2 = aurevoiur,  2 = bye
Word: 2 = laterz,  2 = bye
Word: 2 = bye,  2 = aurevoiur
Word: 2 = aurevoiur,  2 = aurevoiur
Word: 2 = laterz,  2 = aurevoiur
Word: 2 = bye,  2 = laterz
Word: 2 = aurevoiur,  2 = laterz
Word: 2 = laterz,  2 = laterz

仍然没有给出你所追求的结果集(它给出了每个组合) - 但至少它正在进行连接。

我建议尽可能将数据分成两个表,使用Word表 - 带有Id和其他单个列,并有一个转换表 - 其中包含实际的转换,以及外键返回到word表。我怀疑sqlite驱动程序会更好地应对这一点。