📜  NHibernate-映射组件

📅  最后修改于: 2020-11-19 05:36:35             🧑  作者: Mango


在本章中,我们将讨论映射组件。在NHibernate中, component是一个值对象。它没有自己的身份。

  • 这样的例子是货币对象,钱包或钱包中可能有货币,但是该货币的确切身份无关紧要。

  • 它没有自己的主键,但组件本身与拥有对象在同一表中是持久性的。

让我们看一个简单的示例,其中学生有一个地址,该地址是与之关联的Location类的对象。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks;

namespace NHibernateDemoApp { 

   class Student { 
      public virtual int ID { get; set; } 
      public virtual string LastName { get; set; } 
      public virtual string FirstName { get; set; } 
      public virtual StudentAcademicStanding AcademicStanding { get; set; } 
      public virtual Location Address { get; set; } 
   }

   public class Location { 
      public virtual string Street { get; set; } 
      public virtual string City { get; set; } 
      public virtual string Province { get; set; } 
      public virtual string Country { get; set; } 
   }
  
   public enum StudentAcademicStanding { 
      Excellent, 
      Good, 
      Fair, 
      Poor, 
      Terrible 
   } 
}

现在,我们还需要通过执行以下查询来更新数据库,这将首先删除Student表,然后创建一个新表,该表还将包含Location类的列。

DROP TABLE [dbo].[Student]
CREATE TABLE [dbo].[Student] ( 

   [ID] INT IDENTITY (1, 1) NOT NULL, 
   [LastName] NVARCHAR (MAX) NULL, 
   [FirstMidName] NVARCHAR (MAX) NULL, 
   [AcademicStanding] NCHAR(10) NULL, 
   [Street] NVARCHAR (100) NULL, 
   [City] NVARCHAR (100) NULL, 
   [Province] NVARCHAR (100) NULL, 
   [Country] NVARCHAR (100) NULL, 
   CONSTRAINT [PK_dbo.Student] PRIMARY KEY CLUSTERED ([ID] ASC) 

);

现在要映射那些不直接属于Student类的列,但它们是Location类的属性,并且Location类对象是在Student类中定义的。我们需要一个组件来正确映射它。让我们在student.hbm.xml文件中创建一个组件,如以下代码所示。

 
 

    
    
       
         
       
   
       
        
       
      
      
       
          
          
          
          
       
   
    

该组件是地址,并且具有这些不同的属性。有了这些信息,NHibernate现在具有足够的空间来实际映射它。

现在是Program.cs文件,在其中创建并初始化一个新的Student对象,然后将其保存到数据库中。然后它将从数据库中检索列表。

using HibernatingRhinos.Profiler.Appender.NHibernate; 
using NHibernate.Cache; 
using NHibernate.Caches.SysCache; 
using NHibernate.Cfg; 
using NHibernate.Dialect; 
using NHibernate.Driver; 
using NHibernate.Linq; 

using System; 
using System.Linq; 
using System.Reflection;
namespace NHibernateDemoApp { 

   class Program {
    
      static void Main(string[] args) { 
        
         NHibernateProfiler.Initialize(); 
         var cfg = new Configuration();

         String Data Source = asia13797\\sqlexpress;
         String Initial Catalog = NHibernateDemoDB;
         String Integrated Security = True;
         String Connect Timeout = 15;
         String Encrypt = False;
         String TrustServerCertificate = False;
         String ApplicationIntent = ReadWrite;
         String MultiSubnetFailover = False;            
         
         cfg.DataBaseIntegration(x = > { x.ConnectionString = "Data Source + 
            Initial Catalog + Integrated Security + Connect Timeout + Encrypt +
            TrustServerCertificate + ApplicationIntent + MultiSubnetFailover";
                
            x.Driver(); 
            x.Dialect(); 
         }); 
         
         cfg.AddAssembly(Assembly.GetExecutingAssembly()); 
         var sefact = cfg.BuildSessionFactory(); 
            
         using (var session = sefact.OpenSession()) { 
            
            using (var tx = session.BeginTransaction()) { 
               
               var student1 = new Student { 
                  ID = 1, 
                  FirstName = "Allan", 
                  LastName = "Bommer", 
                  AcademicStanding = StudentAcademicStanding.Poor, 
                  
                  Address = new Location { 
                     Street = "123 Street", 
                     City = "Lahore", 
                     Province = "Punjab", 
                     Country = "Pakistan" 
                  } 
               }; 
                    
               session.Save(student1); 
               tx.Commit(); 
               var students = session.Query().ToList();
               Console.WriteLine("\nFetch the complete list again\n"); 
               
               foreach (var student in students) { 
                  Console.WriteLine("{0} \t{1} \t{2} \t{3} \t{4} \t{5} \t{6} \t{7}", 
                     student.ID, 
                     student.FirstName, 
                     student.LastName, 
                     student.AcademicStanding, 
                     student.Address.Street, 
                     student.Address.City, 
                     student.Address.Province, 
                     student.Address.Country
                  ); 
               } 
            } 
                
            Console.ReadLine(); 
         } 
      }
   } 
}

现在我们可以运行该应用程序,NHibernate可以将这些值保存到数据库中。运行应用程序时,将看到以下输出。

Fetch the complete list again

2 Allan Bommer Poor 123 Street Lahore Punjab Pakistan

这是数据库中的值。

价值观数据库

这些组件使我们能够将数据库表中的列分离为它们自己的单独类。

  • 这里要注意的另一件事是因为Location是一个类,而不是一个实体。

  • 这是一个值类型对象,没有自己的主键。

  • 它与包含它的Student保存在同一表中。

  • 这就是为什么我们在这里使用组件。

  • 这提供了很大的灵活性来更改我们的类层,如何定义类以及如何布置数据库。