如何反思EntityFramework类(模型第一种方法)?

时间:2013-04-13 04:56:39

标签: c# reflection entity-framework-4.1

使用DataBase First时可以创建为VisualStudio生成的类的实例吗?

我的意思是,我使用t4模板和命令“生成代码”,使用T4模板进行MVC3工具更新,从db创建我的类,具有多对多的关系。

我可以使用反射来“填充”实例的属性,例如在不同的程序集(dll)中此类的“Student”吗?

例如有3个表格: “课程” “学生们” “studentsCourses”

我将有3个实体,用于课程,一个用于学生,一个用于关系。 我可以收到一个对象或输入“学生”并使用反射来“填充”它的所有属性吗?如果是,我怎么能实现这个目标?

我已经知道我可以通过引用接收对象作为“对象类型”(使用泛型)但我无法弄清楚如何创建/填充复杂属性(例如在studentsCourses属性中)

提前感谢任何建议。

这里我让脚本创建表和数据库“COURSES_TEST”:

USE [master]
GO
/****** Object:  Database [COURSES_TEST]    Script Date: 04/12/2013 23:47:18 ******/
CREATE DATABASE [COURSES_TEST] ON  PRIMARY 
( NAME = N'COURSES_TEST', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL10.SQLEXPRESS\MSSQL\DATA\COURSES_TEST.mdf' , SIZE = 2048KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
 LOG ON 
( NAME = N'COURSES_TEST_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL10.SQLEXPRESS\MSSQL\DATA\COURSES_TEST_log.ldf' , SIZE = 1024KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO
ALTER DATABASE [COURSES_TEST] SET COMPATIBILITY_LEVEL = 100
GO
IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
begin
EXEC [COURSES_TEST].[dbo].[sp_fulltext_database] @action = 'enable'
end
GO
ALTER DATABASE [COURSES_TEST] SET ANSI_NULL_DEFAULT OFF
GO
ALTER DATABASE [COURSES_TEST] SET ANSI_NULLS OFF
GO
ALTER DATABASE [COURSES_TEST] SET ANSI_PADDING OFF
GO
ALTER DATABASE [COURSES_TEST] SET ANSI_WARNINGS OFF
GO
ALTER DATABASE [COURSES_TEST] SET ARITHABORT OFF
GO
ALTER DATABASE [COURSES_TEST] SET AUTO_CLOSE OFF
GO
ALTER DATABASE [COURSES_TEST] SET AUTO_CREATE_STATISTICS ON
GO
ALTER DATABASE [COURSES_TEST] SET AUTO_SHRINK OFF
GO
ALTER DATABASE [COURSES_TEST] SET AUTO_UPDATE_STATISTICS ON
GO
ALTER DATABASE [COURSES_TEST] SET CURSOR_CLOSE_ON_COMMIT OFF
GO
ALTER DATABASE [COURSES_TEST] SET CURSOR_DEFAULT  GLOBAL
GO
ALTER DATABASE [COURSES_TEST] SET CONCAT_NULL_YIELDS_NULL OFF
GO
ALTER DATABASE [COURSES_TEST] SET NUMERIC_ROUNDABORT OFF
GO
ALTER DATABASE [COURSES_TEST] SET QUOTED_IDENTIFIER OFF
GO
ALTER DATABASE [COURSES_TEST] SET RECURSIVE_TRIGGERS OFF
GO
ALTER DATABASE [COURSES_TEST] SET  DISABLE_BROKER
GO
ALTER DATABASE [COURSES_TEST] SET AUTO_UPDATE_STATISTICS_ASYNC OFF
GO
ALTER DATABASE [COURSES_TEST] SET DATE_CORRELATION_OPTIMIZATION OFF
GO
ALTER DATABASE [COURSES_TEST] SET TRUSTWORTHY OFF
GO
ALTER DATABASE [COURSES_TEST] SET ALLOW_SNAPSHOT_ISOLATION OFF
GO
ALTER DATABASE [COURSES_TEST] SET PARAMETERIZATION SIMPLE
GO
ALTER DATABASE [COURSES_TEST] SET READ_COMMITTED_SNAPSHOT OFF
GO
ALTER DATABASE [COURSES_TEST] SET HONOR_BROKER_PRIORITY OFF
GO
ALTER DATABASE [COURSES_TEST] SET  READ_WRITE
GO
ALTER DATABASE [COURSES_TEST] SET RECOVERY SIMPLE
GO
ALTER DATABASE [COURSES_TEST] SET  MULTI_USER
GO
ALTER DATABASE [COURSES_TEST] SET PAGE_VERIFY CHECKSUM
GO
ALTER DATABASE [COURSES_TEST] SET DB_CHAINING OFF
GO
USE [COURSES_TEST]
GO
/****** Object:  Table [dbo].[students]    Script Date: 04/12/2013 23:47:19 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[students](
    [studentID] [int] IDENTITY(1,1) NOT NULL,
    [name] [nvarchar](50) NULL,
    [lastName] [nvarchar](50) NULL,
 CONSTRAINT [PK_students] PRIMARY KEY CLUSTERED 
(
    [studentID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  Table [dbo].[courses]    Script Date: 04/12/2013 23:47:19 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[courses](
    [courseID] [int] IDENTITY(1,1) NOT NULL,
    [course] [nchar](10) NULL,
    [description] [nvarchar](50) NULL,
 CONSTRAINT [PK_courses] PRIMARY KEY CLUSTERED 
(
    [courseID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  Table [dbo].[Studentscourses]    Script Date: 04/12/2013 23:47:19 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Studentscourses](
    [courseStudentID] [int] IDENTITY(1,1) NOT NULL,
    [courseID] [int] NULL,
    [studentID] [int] NULL,
 CONSTRAINT [PK_Studentscourses] PRIMARY KEY CLUSTERED 
(
    [courseStudentID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  ForeignKey [FK_Studentscourses_courses]    Script Date: 04/12/2013 23:47:19 ******/
ALTER TABLE [dbo].[Studentscourses]  WITH CHECK ADD  CONSTRAINT [FK_Studentscourses_courses] FOREIGN KEY([courseID])
REFERENCES [dbo].[courses] ([courseID])
GO
ALTER TABLE [dbo].[Studentscourses] CHECK CONSTRAINT [FK_Studentscourses_courses]
GO
/****** Object:  ForeignKey [FK_Studentscourses_students]    Script Date: 04/12/2013 23:47:19 ******/
ALTER TABLE [dbo].[Studentscourses]  WITH CHECK ADD  CONSTRAINT [FK_Studentscourses_students] FOREIGN KEY([studentID])
REFERENCES [dbo].[students] ([studentID])
GO
ALTER TABLE [dbo].[Studentscourses] CHECK CONSTRAINT [FK_Studentscourses_students]
GO

1 个答案:

答案 0 :(得分:1)

如果我理解你,EF会产生类似

的内容
class YourStudent
{
    public int studentId { get; set; }
    public string name { get; set; }
    public string lastName { get; set; }
    public virtual ICollection<Course> Courses { get; set; }
}

并且有

class TheirStudent
{
    public int studentId {get;set;}
    public string name { get; set; }
    public string lastName { get; set; }
}

并且您希望将来自TheyStudent实例的值填充到YourStudent实例中。

也许像

YourStudent s1;
TheirStudent s2;
Type t = typeof(YourStudent);
Type t2 = typeof(TheirStudent);

foreach (PropertyInfo pinfo in t.GetProperties()) 
{
    if (pinfo.GetGetMethod().IsVirtual &&
        pinfo.PropertyType.IsGenericType &&
        pinfo.PropertyType.GetGenericTypeDefinition() == typeof(ICollection<>))
    {

        // This is [probably] a nav property. Courses would be in here
    }
    else if (pinfo.GetGetMethod().IsVirtual)
    {
        // if you have 0..1 or 1..1 nav properties you might muck around in here
    }
    else if (!pinfo.GetGetMethod().IsVirtual)
    {
        // This is [probably] a column - studentId, name, etc would be here

        // you could pull values over like so:
        PropertyInfo pinfo2 = (from ps in t2.GetProperties() 
                               where ps.Name == pinfo.Name 
                               select ps).SingleOrDefault();
        if (pinfo2 != null)
        {
            object value = pinfo2.GetValue(s2, new object[] { });
            pinfo.SetValue(s1, value, new object[] { });
        }
    }
}