Сообщений 0 Оценка 165 Оценить |
Для чтения объектов разных типов из одного источника данных может использоваться фабрика объектов - возможность, предоставляемая классом TypeAccessor. Метод CreateInstanceEx класса TypeAccessor всегда перед созданием экземпляра объекта проверяет значение свойства ObjectFactory и если оно не равно null, то управление создания объекта передаётся фабрике ассоциированной со свойством ObjectFactory. Свойство ObjectFactory может быть проинициализировано либо вручную в начале выполнения программы, либо, как следующем примере, с помощью атрибута ObjectFactoryAttribute.
using System; using System.Collections.Generic; using NUnit.Framework; using BLToolkit.Data; using BLToolkit.Mapping; using BLToolkit.Reflection; namespace HowTo.Reflection { [TestFixture] public class ObjectFactoryTest { [ObjectFactory(typeof(Person.ObjectFactory))] public class Person { [MapField("PersonID")] public int ID; public string LastName; public string FirstName; public string MiddleName; class ObjectFactory : IObjectFactory { public object CreateInstance(TypeAccessor typeAccessor, InitContext context) { // Get the object type indicator field. // object objectType = context.DataSource.GetValue(context.SourceObject, "PersonType"); // Target ObjectMapper must be changed in order to provide correct mapping. // switch ((string)objectType) { case "D": context.ObjectMapper = ObjectMapper<Doctor>. Instance; break; case "P": context.ObjectMapper = ObjectMapper<Patient>.Instance; break; } // Create an object instance. // Do not call ObjectMapper.CreateInstance as it will lead to infinite recursion. // return context.ObjectMapper.TypeAccessor.CreateInstance(context); } } } public class Doctor : Person { public string Taxonomy; } public class Patient : Person { public string Diagnosis; } [Test] public void Test() { using (DbManager db = new DbManager()) { List<Person> list = db .SetCommand(@" SELECT ps.*, d.Taxonomy, p.Diagnosis, CASE WHEN d.PersonID IS NOT NULL THEN 'D' WHEN p.PersonID IS NOT NULL THEN 'P' END as PersonType FROM Person ps LEFT JOIN Doctor d ON d.PersonID = ps.PersonID LEFT JOIN Patient p ON p.PersonID = ps.PersonID ORDER BY ps.PersonID") .ExecuteList<Person>(); Assert.AreEqual(list[0].GetType(), typeof(Doctor)); Assert.AreEqual(list[1].GetType(), typeof(Patient)); if (list.Count > 2) Assert.AreEqual(list[2].GetType(), typeof(Person)); } } } } |
SQL скрипт для создания базы данных:
--CREATE DATABASE BLToolkitData ON PRIMARY --(NAME=N'BLToolkitTest', FILENAME=N'C:\Data\MSSQL.1\MSSQL\DATA\BLToolkitData.mdf', SIZE=3072KB, FILEGROWTH=1024KB) --LOG ON --(NAME=N'BLToolkitTest_log', FILENAME=N'C:\Data\MSSQL.1\MSSQL\DATA\BLToolkitData_log.ldf', SIZE=1024KB, FILEGROWTH=10%) --GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID('Doctor') AND type in (N'U')) BEGIN DROP TABLE Doctor END IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID('Patient') AND type in (N'U')) BEGIN DROP TABLE Patient END -- Person Table IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID('Person') AND type in (N'U')) BEGIN DROP TABLE Person END CREATE TABLE Person ( PersonID int NOT NULL IDENTITY(1,1) CONSTRAINT PK_Person PRIMARY KEY CLUSTERED, FirstName nvarchar(50) NOT NULL, LastName nvarchar(50) NOT NULL, MiddleName nvarchar(50) NULL, Gender char(1) NOT NULL CONSTRAINT CK_Person_Gender CHECK (Gender in ('M', 'F', 'U', 'O')) ) ON [PRIMARY] GO INSERT INTO Person (FirstName, LastName, Gender) VALUES ('John', 'Pupkin', 'M') INSERT INTO Person (FirstName, LastName, Gender) VALUES ('Tester', 'Testerson', 'M') GO -- Doctor Table Extension CREATE TABLE Doctor ( PersonID int NOT NULL CONSTRAINT PK_Doctor PRIMARY KEY CLUSTERED CONSTRAINT FK_Doctor_Person FOREIGN KEY REFERENCES Person ([PersonID]) ON UPDATE CASCADE ON DELETE CASCADE, Taxonomy nvarchar(50) NOT NULL ) ON [PRIMARY] GO INSERT INTO Doctor (PersonID, Taxonomy) VALUES (1, 'Psychiatry') GO -- Patient Table Extension CREATE TABLE Patient ( PersonID int NOT NULL CONSTRAINT PK_Patient PRIMARY KEY CLUSTERED CONSTRAINT FK_Patient_Person FOREIGN KEY REFERENCES Person ([PersonID]) ON UPDATE CASCADE ON DELETE CASCADE, Diagnosis nvarchar(256) NOT NULL ) ON [PRIMARY] GO INSERT INTO Patient (PersonID, Diagnosis) VALUES (2, 'Hallucination with Paranoid Bugs'' Delirium of Persecution') GO |
App.config:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings> <add key = "ConnectionString" value = "Server=.;Database=BLToolkitData;Integrated Security=SSPI"/> </appSettings> </configuration> |
Сообщений 0 Оценка 165 Оценить |