繁体   English   中英

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

[英]LINQ generates wrong sql query with system.data.sqlite

我有以下模型:

[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的结合使用效果很差。 推荐的解决方案是使用实体框架。

我认为问题在于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和其他单列),以及使用转换表(包含实际的转换)和返回到单词表的外键。 我怀疑sqlite驱动程序会更好地应对这种情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM