【发布时间】:2014-06-17 12:25:17
【问题描述】:
我有以下型号:
[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 配合得非常糟糕。推荐的解决方案是使用实体框架。
【问题讨论】:
-
你加入同一张表的同一列有什么原因吗?
-
是的,这是设计使然。这个想法是我将不同语言的单词保存在“单词”表中。具有相同含义的单词具有相同的 id(但不同的 language_ids)。我想把一个词连同它的翻译一起来。问题中的查询是一个最小示例,它展示了我遇到的问题。如您所见,linq 将连接条件从
w1.id = w2.id(在linq 中)更改为w1.id = w1.id(在sql 中)。显然,这没有意义。我不明白为什么会这样。