[英]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};
显然,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.