我有词典/词库的Word模型:
public class Word
{
public virtual string Text { get; set; }
public virtual IList<Word> Synonyms { get; set; }
public virtual IList<Word> Antonyms { get; set; }
}
每个Word都有很多同义词和反义词。 Word有一个映射:
public class WordMapping : ClassMap<Word>
{
Id(x => x.Text);
HasMany(x => x.Synonyms);
HasMany(x => x.Antonyms);
}
在我的控制器中,我有一个单词的简单查找方法:
public ActionResult Word(string word)
{
using (var session = MvcApplication.SessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
var result = session.QueryOver<Word>()
.Where(w => w.Text == word)
.SingleOrDefault();
if(result == null)
RedirectToAction("InvalidWord");
ViewBag.Synonyms = result.Synonyms.Select(t => t.Text);
ViewBag.Antonyms = result.Antonyms.Select(t => t.Text);
return View(result);
}
}
}
当我在视图中打印出ViewBag集合时,它们都是相同的。它们是两个袋子中看似任意选择的元素,但不是整个袋子。
更新:以下是我将Word提交到数据库的代码,如果有帮助的话。当我在提交后打印出words
时,所有同义词都是正确的。
List<Word> words;
...
using (var session = MvcApplication.SessionFactory.OpenSession())
{
// populate the database
using (var transaction = session.BeginTransaction())
{
foreach (var word in words)
session.Save(word);
transaction.Commit();
}
}
PrintWords(words);
答案 0 :(得分:3)
尝试使用标识列Id
而不是Text
属性:
public class Word
{
public virtual int Id { get; set; }
public virtual string Text { get; set; }
public virtual IList<Word> Synonyms { get; set; }
public virtual IList<Word> Antonyms { get; set; }
}
然后:
Id(x => x.Id);
Map(x => x.Text);
HasMany(x => x.Synonyms);
HasMany(x => x.Antonyms);
更新:
这是一个完整的工作示例(使用SQLite和控制台应用程序来简化,但类似的技术可以在您的Web应用程序中应用):
// Domain layer
public class Word
{
public virtual int Id { get; set; }
public virtual string Text { get; set; }
public virtual IList<Word> Synonyms { get; set; }
public virtual IList<Word> Antonyms { get; set; }
}
// Mapping layer
public class WordMapping : ClassMap<Word>
{
public WordMapping()
{
Id(x => x.Id).UnsavedValue(0);
Map(x => x.Text);
HasMany(x => x.Synonyms).Cascade.AllDeleteOrphan();
HasMany(x => x.Antonyms).Cascade.AllDeleteOrphan();
}
}
// Data access layer
class Program : InMemoryDatabase
{
static void Main(string[] args)
{
using (var p = new Program())
{
// save some dummy data into the database
var word = new Word
{
Text = "myword",
Synonyms = new[]
{
new Word { Text = "synonym 1" },
new Word { Text = "synonym 2" },
}.ToList(),
Antonyms = new[]
{
new Word { Text = "antonym 1" },
}.ToList()
};
using (var tx = p.Session.BeginTransaction())
{
p.Session.Save(word);
tx.Commit();
}
// and now let's query the database
using (var tx = p.Session.BeginTransaction())
{
var result = p.Session
.QueryOver<Word>()
.Where(w => w.Text == "myword")
.SingleOrDefault();
var synonyms = result.Synonyms.Select(t => t.Text).ToArray();
Console.WriteLine("-- Synonyms --");
foreach (var item in synonyms)
{
Console.WriteLine(item);
}
var antonyms = result.Antonyms.Select(t => t.Text).ToArray();
Console.WriteLine("-- Antonyms --");
foreach (var item in antonyms)
{
Console.WriteLine(item);
}
}
}
}
}
public abstract class InMemoryDatabase : IDisposable
{
private static Configuration _configuration;
private static ISessionFactory _sessionFactory;
protected ISession Session { get; set; }
protected InMemoryDatabase()
{
_sessionFactory = CreateSessionFactory();
Session = _sessionFactory.OpenSession();
BuildSchema(Session);
}
private static ISessionFactory CreateSessionFactory()
{
return Fluently.Configure()
.Database(SQLiteConfiguration.Standard.InMemory().ShowSql())
.Mappings(M => M.FluentMappings.AddFromAssemblyOf<WordMapping>())
.ExposeConfiguration(Cfg => _configuration = Cfg)
.BuildSessionFactory();
}
private static void BuildSchema(ISession Session)
{
SchemaExport export = new SchemaExport(_configuration);
export.Execute(true, true, false, Session.Connection, null);
}
public void Dispose()
{
Session.Dispose();
}
}