Cascade 使用 Fluent NHibernate AutoMapping 进行保存 - 旧答案仍然有效吗?

发布于 2024-08-21 06:07:29 字数 2724 浏览 4 评论 0 原文

我想做的正是这个问题所要求的: 使用 Fluent NHibernate AutoMapping 进行级联保存

使用 Fluent Nhibernate 映射打开“级联”使用一次调用对所有类和关系类型全局一次,而不是为每个映射单独设置。

前面问题的答案看起来不错,但我担心 Fluent Nhibernate API 去年改变了它的 .WithConvention 语法并破坏了答案......要么是这样,要么是我遗漏了一些东西。

我不断收到一堆与 IOneToOnePart、IManyToOnePart 及其所有变体相关的命名空间未找到错误:

“找不到类型或命名空间名称‘IOneToOnePart’(您是否缺少 using 指令或程序集引用?)

”我已经尝试过官方示例 dll、RTM dll 和最新版本,但它们似乎都无法使 VS 2008 看到所需的命名空间。

第二个问题是我想将该类与我的 AutoPersistenceModel 一起使用 但我不确定这条线在哪里: .ConventionDiscovery.AddFromAssemblyOf() 在我的工厂创建方法中。

 private static ISessionFactory CreateSessionFactory()
            {

                return Fluently.Configure()
                  .Database(SQLiteConfiguration.Standard.UsingFile(DbFile))
                  .Mappings(m => m.AutoMappings
                        .Add(AutoMap.AssemblyOf<Shelf>(type => type.Namespace.EndsWith("Entities"))
                                .Override<Shelf>(map =>
                                {
                                    map.HasManyToMany(x => x.Products).Cascade.All();
                                })
                             )

                      )//emd mappings
                .ExposeConfiguration(BuildSchema)
                .BuildSessionFactory();//finalizes the whole thing to send back. 

            }

下面是我正在尝试的类和 using 语句

   using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;

    using FluentNHibernate.Conventions;
    using FluentNHibernate.Cfg;
    using FluentNHibernate.Cfg.Db;
    using NHibernate;
    using NHibernate.Cfg;
    using NHibernate.Tool.hbm2ddl;
    using FluentNHibernate.Mapping;


    namespace TestCode
    {
        public class CascadeAll : IHasOneConvention, IHasManyConvention, IReferenceConvention
        {
            public bool Accept(IOneToOnePart target)
            {
                return true;
            }

            public void Apply(IOneToOnePart target)
            {
                target.Cascade.All();
            }

            public bool Accept(IOneToManyPart target)
            {
                return true;
            }

            public void Apply(IOneToManyPart target)
            {
                target.Cascade.All();
            }

            public bool Accept(IManyToOnePart target)
            {
                return true;
            }

            public void Apply(IManyToOnePart target)
            {
                target.Cascade.All();
            }
        }

    }

I want to do exactly what this question asks:
Cascade Saves with Fluent NHibernate AutoMapping

Using Fluent Nhibernate Mappings to turn on "cascade" globally once for all classes and relation types using one call rather than setting it for each mapping individually.

The answer to the earlier question looks great, but I'm afraid that the Fluent Nhibernate API altered its .WithConvention syntax last year and broke the answer... either that or I'm missing something.

I keep getting a bunch of name space not found errors relating to the IOneToOnePart, IManyToOnePart and all their variations:

"The type or namespace name 'IOneToOnePart' could not be found (are you missing a using directive or an assembly reference?)"

I've tried the official example dll's, the RTM dll's and the latest build and none of them seem to make VS 2008 see the required namespace.

The second problem is that I want to use the class with my AutoPersistenceModel
but I'm not sure where to this line:
.ConventionDiscovery.AddFromAssemblyOf()
in my factory creation method.

 private static ISessionFactory CreateSessionFactory()
            {

                return Fluently.Configure()
                  .Database(SQLiteConfiguration.Standard.UsingFile(DbFile))
                  .Mappings(m => m.AutoMappings
                        .Add(AutoMap.AssemblyOf<Shelf>(type => type.Namespace.EndsWith("Entities"))
                                .Override<Shelf>(map =>
                                {
                                    map.HasManyToMany(x => x.Products).Cascade.All();
                                })
                             )

                      )//emd mappings
                .ExposeConfiguration(BuildSchema)
                .BuildSessionFactory();//finalizes the whole thing to send back. 

            }

Below is the class and using statements I'm trying

   using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;

    using FluentNHibernate.Conventions;
    using FluentNHibernate.Cfg;
    using FluentNHibernate.Cfg.Db;
    using NHibernate;
    using NHibernate.Cfg;
    using NHibernate.Tool.hbm2ddl;
    using FluentNHibernate.Mapping;


    namespace TestCode
    {
        public class CascadeAll : IHasOneConvention, IHasManyConvention, IReferenceConvention
        {
            public bool Accept(IOneToOnePart target)
            {
                return true;
            }

            public void Apply(IOneToOnePart target)
            {
                target.Cascade.All();
            }

            public bool Accept(IOneToManyPart target)
            {
                return true;
            }

            public void Apply(IOneToManyPart target)
            {
                target.Cascade.All();
            }

            public bool Accept(IManyToOnePart target)
            {
                return true;
            }

            public void Apply(IManyToOnePart target)
            {
                target.Cascade.All();
            }
        }

    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

心安伴我暖 2024-08-28 06:07:29

我发现对整个项目执行此操作的最简单方法是使用 DefaultCascade

.Conventions.Add( DefaultCascade.All() );     

转到 “最简单的约定” 部分对此进行了说明,并列出了其他内容。

编辑:
以下是 Wiki 中的列表:

Table.Is(x => x.EntityType.Name + "Table")
PrimaryKey.Name.Is(x => "ID")
AutoImport.Never()
DefaultAccess.Field()
DefaultCascade.All()
DefaultLazy.Always()
DynamicInsert.AlwaysTrue()
DynamicUpdate.AlwaysTrue()
OptimisticLock.Is(x => x.Dirty())
Cache.Is(x => x.AsReadOnly())
ForeignKey.EndsWith("ID")

警告 - Wiki 中的某些方法名称可能是错误的。我用我可以验证的内容(即 DefaultCascade 和 DefaultLazy)编辑了 Wiki,但无法保证其余内容。但如果需要的话,您应该能够通过 Intellisense 找出正确的名称。

The easiest way I've found to do this for a whole project is to use DefaultCascade:

.Conventions.Add( DefaultCascade.All() );     

Go to "The Simplest Conventions" section on the wiki, for this, and a list of others.

Edit:
Here's the list from the Wiki:

Table.Is(x => x.EntityType.Name + "Table")
PrimaryKey.Name.Is(x => "ID")
AutoImport.Never()
DefaultAccess.Field()
DefaultCascade.All()
DefaultLazy.Always()
DynamicInsert.AlwaysTrue()
DynamicUpdate.AlwaysTrue()
OptimisticLock.Is(x => x.Dirty())
Cache.Is(x => x.AsReadOnly())
ForeignKey.EndsWith("ID")

A word of warning - some of the method names in the Wiki may be wrong. I edited the Wiki with what I could verify (i.e. DefaultCascade and DefaultLazy), but can't vouch for the rest. But you should be able to figure out the proper names with Intellisense if the need arises.

停滞 2024-08-28 06:07:29

这是一个类似于入门指南的完整工作示例 https://github.com /jagregory/ Fluent-nhibernate/wiki/入门

    //=====CONSOLE MAIN
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    using FluentNHibernate.Cfg;
    using FluentNHibernate.Cfg.Db;
    using NHibernate;
    using NHibernate.Cfg;
    using NHibernate.Tool.hbm2ddl;
    using System.IO;
    using FluentNHibernate.Automapping;
    using App4.Entities;
    using System.Diagnostics;

    namespace App4
    {
        class Program
        {
            static void Main(string[] args)
            {
                // create our NHibernate session factory
                var sessionFactory = CreateSessionFactory();

                using (var session = sessionFactory.OpenSession())
                {
                    // populate the database
                    using (var transaction = session.BeginTransaction())
                    {
                        // create a couple of Stores each with some Products and Employees
                        var topShelf = new Shelf();
                        var sw = new Stopwatch();
                        sw.Start();
                        for (var i = 0; i < 1000; i++)
                        {
                            var potatoes = new Product { Name = "Potatoes" + i.ToString(), Price = 3.60 + i };
                            var meat = new Product { Name = "Meat" + i.ToString(), Price = 4.49 + i };
                            //session.SaveOrUpdate(potatoes); //===<<cascading save handles this :-)
                            //session.SaveOrUpdate(meat);
                            topShelf.Products.Add(meat);
                            topShelf.Products.Add(potatoes);
                        }
                        sw.Stop();

                        session.SaveOrUpdate(topShelf);
                        //session.SaveOrUpdate(superMart);
                        transaction.Commit();

                        Console.WriteLine("Add Items: " + sw.ElapsedMilliseconds);
                    }
                }

                using (var session = sessionFactory.OpenSession())
                {
                    // retreive all stores and display them
                    using (session.BeginTransaction())
                    {
                        var shelves = session.CreateCriteria(typeof(Shelf)).List<Shelf>();

                        foreach (var store in shelves)
                        {
                            WriteShelfPretty(store);
                        }
                    }
                }

                Console.ReadLine();
            }

            private const string DbFile = "FIVEProgram.db";
            private static ISessionFactory CreateSessionFactory()
            {
                return Fluently.Configure()
                  .Database(SQLiteConfiguration.Standard.UsingFile(DbFile))
                  .Mappings(m => m.AutoMappings
                        .Add(AutoMap.AssemblyOf<Shelf>(type => type.Namespace.EndsWith("Entities"))
                                .Override<Shelf>(map =>
                                {
                                    map.HasManyToMany(x => x.Products);//.Cascade.All();
                                })
                                .Conventions.AddFromAssemblyOf<CascadeAll>()
                             )

                      ) //emd mappings
                .ExposeConfiguration(BuildSchema)//Delete and remake db (see function below)
                .BuildSessionFactory();//finalizes the whole thing to send back. 

            }

            private static void BuildSchema(Configuration config)
            {
                // delete the existing db on each run
                if (File.Exists(DbFile))
                    File.Delete(DbFile);

                // this NHibernate tool takes a configuration (with mapping info in)
                // and exports a database schema from it
                new SchemaExport(config)
                    .Create(false, true);
            }

            private static void WriteShelfPretty(Shelf shelf)
            {
                Console.WriteLine(shelf.Id);
                Console.WriteLine("  Products:");

                foreach (var product in shelf.Products)
                {
                    Console.WriteLine("    " + product.Name);
                }

                Console.WriteLine();
            }

        }



    }


//Data Classes
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace App4.Entities 
{
    public class Product
    {
        public virtual int Id { get; private set; }
        public virtual string Name { get; set; }
        public virtual double Price { get; set; }
    }

    public class Shelf
    {
        public virtual int Id { get; private set; }
        public virtual IList<Product> Products { get; private set; }

        public Shelf()
        {
            Products = new List<Product>();
        }
    }
}



//Cascade All Helper Class
using FluentNHibernate.Conventions;
using FluentNHibernate.Conventions.AcceptanceCriteria;
using FluentNHibernate.Conventions.Inspections;
using FluentNHibernate.Conventions.Instances;
using System;
using System.Collections.Generic;


namespace App4
{
    public class CascadeAll : 
        IHasOneConvention, //Actually Apply the convention
        IHasManyConvention, 
        IReferenceConvention, 
        IHasManyToManyConvention,

        IHasOneConventionAcceptance, //Test to see if we should use the convention
        IHasManyConventionAcceptance, //I think we could skip these since it will always be true
        IReferenceConventionAcceptance, //adding them for reference later
        IHasManyToManyConventionAcceptance
    {

        //One to One

        public void Accept(IAcceptanceCriteria<IOneToOneInspector> criteria)
        {
            //criteria.Expect(x => (true));
        }

        public void Apply(IOneToOneInstance instance)
        {
            instance.Cascade.All();
        }




        //One to Many

        public void Accept(IAcceptanceCriteria<IOneToManyCollectionInspector> criteria)
        {
            //criteria.Expect(x => (true));
        }

        public void Apply(IOneToManyCollectionInstance instance)
        {
            instance.Cascade.All();
        }




        //Many to One

        public void Accept(IAcceptanceCriteria<IManyToOneInspector> criteria)
        {
           // criteria.Expect(x => (true));
        }

        public void Apply(IManyToOneInstance instance)
        {
            instance.Cascade.All();
        }





        //Many to Many

        public void Accept(IAcceptanceCriteria<IManyToManyCollectionInspector> criteria)
        {
           // criteria.Expect(x => (true));
        }

        public void Apply(IManyToManyCollectionInstance instance)
        {
            instance.Cascade.All();
        }



    }


}

Here's a full working example similar to the Getting Started guide https://github.com/jagregory/fluent-nhibernate/wiki/Getting-started

    //=====CONSOLE MAIN
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    using FluentNHibernate.Cfg;
    using FluentNHibernate.Cfg.Db;
    using NHibernate;
    using NHibernate.Cfg;
    using NHibernate.Tool.hbm2ddl;
    using System.IO;
    using FluentNHibernate.Automapping;
    using App4.Entities;
    using System.Diagnostics;

    namespace App4
    {
        class Program
        {
            static void Main(string[] args)
            {
                // create our NHibernate session factory
                var sessionFactory = CreateSessionFactory();

                using (var session = sessionFactory.OpenSession())
                {
                    // populate the database
                    using (var transaction = session.BeginTransaction())
                    {
                        // create a couple of Stores each with some Products and Employees
                        var topShelf = new Shelf();
                        var sw = new Stopwatch();
                        sw.Start();
                        for (var i = 0; i < 1000; i++)
                        {
                            var potatoes = new Product { Name = "Potatoes" + i.ToString(), Price = 3.60 + i };
                            var meat = new Product { Name = "Meat" + i.ToString(), Price = 4.49 + i };
                            //session.SaveOrUpdate(potatoes); //===<<cascading save handles this :-)
                            //session.SaveOrUpdate(meat);
                            topShelf.Products.Add(meat);
                            topShelf.Products.Add(potatoes);
                        }
                        sw.Stop();

                        session.SaveOrUpdate(topShelf);
                        //session.SaveOrUpdate(superMart);
                        transaction.Commit();

                        Console.WriteLine("Add Items: " + sw.ElapsedMilliseconds);
                    }
                }

                using (var session = sessionFactory.OpenSession())
                {
                    // retreive all stores and display them
                    using (session.BeginTransaction())
                    {
                        var shelves = session.CreateCriteria(typeof(Shelf)).List<Shelf>();

                        foreach (var store in shelves)
                        {
                            WriteShelfPretty(store);
                        }
                    }
                }

                Console.ReadLine();
            }

            private const string DbFile = "FIVEProgram.db";
            private static ISessionFactory CreateSessionFactory()
            {
                return Fluently.Configure()
                  .Database(SQLiteConfiguration.Standard.UsingFile(DbFile))
                  .Mappings(m => m.AutoMappings
                        .Add(AutoMap.AssemblyOf<Shelf>(type => type.Namespace.EndsWith("Entities"))
                                .Override<Shelf>(map =>
                                {
                                    map.HasManyToMany(x => x.Products);//.Cascade.All();
                                })
                                .Conventions.AddFromAssemblyOf<CascadeAll>()
                             )

                      ) //emd mappings
                .ExposeConfiguration(BuildSchema)//Delete and remake db (see function below)
                .BuildSessionFactory();//finalizes the whole thing to send back. 

            }

            private static void BuildSchema(Configuration config)
            {
                // delete the existing db on each run
                if (File.Exists(DbFile))
                    File.Delete(DbFile);

                // this NHibernate tool takes a configuration (with mapping info in)
                // and exports a database schema from it
                new SchemaExport(config)
                    .Create(false, true);
            }

            private static void WriteShelfPretty(Shelf shelf)
            {
                Console.WriteLine(shelf.Id);
                Console.WriteLine("  Products:");

                foreach (var product in shelf.Products)
                {
                    Console.WriteLine("    " + product.Name);
                }

                Console.WriteLine();
            }

        }



    }


//Data Classes
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace App4.Entities 
{
    public class Product
    {
        public virtual int Id { get; private set; }
        public virtual string Name { get; set; }
        public virtual double Price { get; set; }
    }

    public class Shelf
    {
        public virtual int Id { get; private set; }
        public virtual IList<Product> Products { get; private set; }

        public Shelf()
        {
            Products = new List<Product>();
        }
    }
}



//Cascade All Helper Class
using FluentNHibernate.Conventions;
using FluentNHibernate.Conventions.AcceptanceCriteria;
using FluentNHibernate.Conventions.Inspections;
using FluentNHibernate.Conventions.Instances;
using System;
using System.Collections.Generic;


namespace App4
{
    public class CascadeAll : 
        IHasOneConvention, //Actually Apply the convention
        IHasManyConvention, 
        IReferenceConvention, 
        IHasManyToManyConvention,

        IHasOneConventionAcceptance, //Test to see if we should use the convention
        IHasManyConventionAcceptance, //I think we could skip these since it will always be true
        IReferenceConventionAcceptance, //adding them for reference later
        IHasManyToManyConventionAcceptance
    {

        //One to One

        public void Accept(IAcceptanceCriteria<IOneToOneInspector> criteria)
        {
            //criteria.Expect(x => (true));
        }

        public void Apply(IOneToOneInstance instance)
        {
            instance.Cascade.All();
        }




        //One to Many

        public void Accept(IAcceptanceCriteria<IOneToManyCollectionInspector> criteria)
        {
            //criteria.Expect(x => (true));
        }

        public void Apply(IOneToManyCollectionInstance instance)
        {
            instance.Cascade.All();
        }




        //Many to One

        public void Accept(IAcceptanceCriteria<IManyToOneInspector> criteria)
        {
           // criteria.Expect(x => (true));
        }

        public void Apply(IManyToOneInstance instance)
        {
            instance.Cascade.All();
        }





        //Many to Many

        public void Accept(IAcceptanceCriteria<IManyToManyCollectionInspector> criteria)
        {
           // criteria.Expect(x => (true));
        }

        public void Apply(IManyToManyCollectionInstance instance)
        {
            instance.Cascade.All();
        }



    }


}
べ繥欢鉨o。 2024-08-28 06:07:29

约定的签名已更改。你不使用像ReSharper这样的东西吗?这会让你得出这个结论。

您可以在wiki 上阅读更多关于新约定的信息。

The signature for the conventions has changed. Are you not using something like ReSharper? That would point you to that conclusion.

You can read more about the new conventions on the wiki.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文