C# 自我参照在Fluent NHibernate和MVC3中有许多关系

C# 自我参照在Fluent NHibernate和MVC3中有许多关系,c#,fluent-nhibernate,asp.net-mvc-3,has-many,C#,Fluent Nhibernate,Asp.net Mvc 3,Has Many,我有一个字典/同义词表的单词模型: public class Word { public virtual string Text { get; set; } public virtual IList<Word> Synonyms { get; set; } public virtual IList<Word> Antonyms { get; set; } } 尝试使用标识列Id而不是Text属性: public class Word {

我有一个字典/同义词表的单词模型:

public class Word
{
    public virtual string Text { get; set; }
    public virtual IList<Word> Synonyms { get; set; }
    public virtual IList<Word> Antonyms { get; set; }
}

尝试使用标识列
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; }
}

更新:

下面是一个完整的工作示例(使用SQLite和控制台应用程序来简化,但类似的技术可以应用于web应用程序):

//域层
公共类词
{
公共虚拟整数Id{get;set;}
公共虚拟字符串文本{get;set;}
公共虚拟IList同义词{get;set;}
公共虚拟IList反义词{get;set;}
}
//映射层
公共类WordMapping:ClassMap
{
公共WordMapping()
{
未保存的值(0);
映射(x=>x.Text);
HasMany(x=>x.Synonyms);
HasMany(x=>x.Antonyms);
}
}
//数据访问层
类程序:InMemoryDatabase
{
静态void Main(字符串[]参数)
{
使用(var p=new Program())
{
//将一些虚拟数据保存到数据库中
新单词
{
Text=“myword”,
同义词=新[]
{
新词{Text=“同义词1”},
新词{Text=“同义词2”},
}.ToList(),
反义词=新的[]
{
新词{Text=“antonym 1”},
}托利斯先生()
};
使用(var tx=p.Session.BeginTransaction())
{
p、 Session.Save(word);
tx.Commit();
}
//现在让我们查询数据库
使用(var tx=p.Session.BeginTransaction())
{
var结果=p.会话
.QueryOver()
.Where(w=>w.Text==“myword”)
.SingleOrDefault();
var synonyms=result.synonyms.Select(t=>t.Text.ToArray();
Console.WriteLine(“--同义词--”);
foreach(同义词中的变量项)
{
控制台写入线(项目);
}
var antonyms=result.antonyms.Select(t=>t.Text.ToArray();
Console.WriteLine(“--反义词--”);
foreach(反义词中的可变项)
{
控制台写入线(项目);
}
}
}
}
}
MemoryDatabase中的公共抽象类:IDisposable
{
私有静态配置_配置;
私人静态ISessionFactory_sessionFactory;
受保护的ISession会话{get;set;}
受保护的InMemoryDatabase()
{
_sessionFactory=CreateSessionFactory();
会话=_sessionFactory.OpenSession();
构建模式(会话);
}
私有静态ISessionFactory CreateSessionFactory()
{
流畅地返回。Configure()
.Database(SQLiteConfiguration.Standard.InMemory().ShowSql())
.Mappings(M=>M.FluentMappings.AddFromAssemblyOf())
.ExposeConfiguration(Cfg=>_configuration=Cfg)
.BuildSessionFactory();
}
私有静态void BuildSchema(ISession会话)
{
SchemaExport export=新SchemaExport(_配置);
export.Execute(true、true、false、Session.Connection、null);
}
公共空间处置()
{
Session.Dispose();
}
}

Nope,还是一样的问题。@Darin,我在运行该程序时遇到一个错误:无法从NHibernate.driver.SQLite20Driver创建驱动程序。无论哪种方式,我所做的一切都与我实际程序中的您完全一样,而且它仍然在混合集合。当我实际从文件构建字典时,我打印出同义词/反义词,它们是正确的。@Wesley Tansey,在我的示例中,我使用的是SQLite,因此请确保您引用了
System.Data.SQLite.dll
assembly。我安装了SQLite并引用了它,但仍然会得到相同的错误。@Wesley Tansey,你在.NET4.0上运行这个吗?您是否在x64操作系统上运行此功能?其中有一些警告:
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);
        }
    }
}
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);
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);
// 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();
    }
}