lxl преди 2 години
родител
ревизия
c4feed0c8f

+ 43 - 362
.gitignore

@@ -1,365 +1,46 @@
-## Ignore Visual Studio temporary files, build results, and
-## files generated by popular Visual Studio add-ons.
-##
-## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
+################################################################################
+# 此 .gitignore 文件已由 Microsoft(R) Visual Studio 自动创建。
+################################################################################
 
-# User-specific files
-*.rsuser
 *.suo
-*.user
-*.userosscache
-*.sln.docstates
-
-# User-specific files (MonoDevelop/Xamarin Studio)
-*.userprefs
-
-# Mono auto generated files
-mono_crash.*
-
-# Build results
-[Dd]ebug/
-[Dd]ebugPublic/
-[Rr]elease/
-[Rr]eleases/
-x64/
-x86/
-[Ww][Ii][Nn]32/
-[Aa][Rr][Mm]/
-[Aa][Rr][Mm]64/
-bld/
-[Bb]in/
-[Oo]bj/
-[Oo]ut/
-[Ll]og/
-[Ll]ogs/
-
-# Visual Studio 2015/2017 cache/options directory
-.vs/
-# Uncomment if you have tasks that create the project's static files in wwwroot
-#wwwroot/
-
-# Visual Studio 2017 auto generated files
-Generated\ Files/
-
-# MSTest test Results
-[Tt]est[Rr]esult*/
-[Bb]uild[Ll]og.*
-
-# NUnit
-*.VisualState.xml
-TestResult.xml
-nunit-*.xml
-
-# Build Results of an ATL Project
-[Dd]ebugPS/
-[Rr]eleasePS/
-dlldata.c
-
-# Benchmark Results
-BenchmarkDotNet.Artifacts/
-
-# .NET Core
-project.lock.json
-project.fragment.lock.json
-artifacts/
-
-# ASP.NET Scaffolding
-ScaffoldingReadMe.txt
-
-# StyleCop
-StyleCopReport.xml
-
-# Files built by Visual Studio
-*_i.c
-*_p.c
-*_h.h
-*.ilk
-*.meta
-*.obj
-*.iobj
-*.pch
-*.pdb
-*.ipdb
-*.pgc
-*.pgd
-*.rsp
-*.sbr
-*.tlb
-*.tli
-*.tlh
-*.tmp
-*.tmp_proj
-*_wpftmp.csproj
-*.log
-*.vspscc
-*.vssscc
-.builds
-*.pidb
-*.svclog
-*.scc
-
-# Chutzpah Test files
-_Chutzpah*
-
-# Visual C++ cache files
-ipch/
-*.aps
-*.ncb
-*.opendb
-*.opensdf
-*.sdf
-*.cachefile
-*.VC.db
-*.VC.VC.opendb
-
-# Visual Studio profiler
-*.psess
-*.vsp
-*.vspx
-*.sap
-
-# Visual Studio Trace Files
-*.e2e
-
-# TFS 2012 Local Workspace
-$tf/
-
-# Guidance Automation Toolkit
-*.gpState
-
-# ReSharper is a .NET coding add-in
-_ReSharper*/
-*.[Rr]e[Ss]harper
-*.DotSettings.user
-
-# TeamCity is a build add-in
-_TeamCity*
-
-# DotCover is a Code Coverage Tool
-*.dotCover
-
-# AxoCover is a Code Coverage Tool
-.axoCover/*
-!.axoCover/settings.json
-
-# Coverlet is a free, cross platform Code Coverage Tool
-coverage*.json
-coverage*.xml
-coverage*.info
-
-# Visual Studio code coverage results
-*.coverage
-*.coveragexml
-
-# NCrunch
-_NCrunch_*
-.*crunch*.local.xml
-nCrunchTemp_*
-
-# MightyMoose
-*.mm.*
-AutoTest.Net/
-
-# Web workbench (sass)
-.sass-cache/
-
-# Installshield output folder
-[Ee]xpress/
-
-# DocProject is a documentation generator add-in
-DocProject/buildhelp/
-DocProject/Help/*.HxT
-DocProject/Help/*.HxC
-DocProject/Help/*.hhc
-DocProject/Help/*.hhk
-DocProject/Help/*.hhp
-DocProject/Help/Html2
-DocProject/Help/html
-
-# Click-Once directory
-publish/
-
-# Publish Web Output
-*.[Pp]ublish.xml
-*.azurePubxml
-# Note: Comment the next line if you want to checkin your web deploy settings,
-# but database connection strings (with potential passwords) will be unencrypted
-*.pubxml
-*.publishproj
-
-# Microsoft Azure Web App publish settings. Comment the next line if you want to
-# checkin your Azure Web App publish settings, but sensitive information contained
-# in these scripts will be unencrypted
-PublishScripts/
-
-# NuGet Packages
-*.nupkg
-# NuGet Symbol Packages
-*.snupkg
-# The packages folder can be ignored because of Package Restore
-**/[Pp]ackages/*
-# except build/, which is used as an MSBuild target.
-!**/[Pp]ackages/build/
-# Uncomment if necessary however generally it will be regenerated when needed
-#!**/[Pp]ackages/repositories.config
-# NuGet v3's project.json files produces more ignorable files
-*.nuget.props
-*.nuget.targets
-
-# Microsoft Azure Build Output
-csx/
-*.build.csdef
-
-# Microsoft Azure Emulator
-ecf/
-rcf/
-
-# Windows Store app package directories and files
-AppPackages/
-BundleArtifacts/
-Package.StoreAssociation.xml
-_pkginfo.txt
-*.appx
-*.appxbundle
-*.appxupload
-
-# Visual Studio cache files
-# files ending in .cache can be ignored
-*.[Cc]ache
-# but keep track of directories ending in .cache
-!?*.[Cc]ache/
-
-# Others
-ClientBin/
-~$*
-*~
-*.dbmdl
-*.dbproj.schemaview
-*.jfm
-*.pfx
-*.publishsettings
-orleans.codegen.cs
-
-# Including strong name files can present a security risk
-# (https://github.com/github/gitignore/pull/2483#issue-259490424)
-#*.snk
-
-# Since there are multiple workflows, uncomment next line to ignore bower_components
-# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
-#bower_components/
-
-# RIA/Silverlight projects
-Generated_Code/
-
-# Backup & report files from converting an old project file
-# to a newer Visual Studio version. Backup files are not needed,
-# because we have git ;-)
-_UpgradeReport_Files/
-Backup*/
-UpgradeLog*.XML
-UpgradeLog*.htm
-ServiceFabricBackup/
-*.rptproj.bak
-
-# SQL Server files
-*.mdf
-*.ldf
-*.ndf
-
-# Business Intelligence projects
-*.rdl.data
-*.bim.layout
-*.bim_*.settings
-*.rptproj.rsuser
-*- [Bb]ackup.rdl
-*- [Bb]ackup ([0-9]).rdl
-*- [Bb]ackup ([0-9][0-9]).rdl
-
-# Microsoft Fakes
-FakesAssemblies/
-
-# GhostDoc plugin setting file
-*.GhostDoc.xml
-
-# Node.js Tools for Visual Studio
-.ntvs_analysis.dat
-node_modules/
-
-# Visual Studio 6 build log
-*.plg
-
-# Visual Studio 6 workspace options file
-*.opt
-
-# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
-*.vbw
-
-# Visual Studio LightSwitch build output
-**/*.HTMLClient/GeneratedArtifacts
-**/*.DesktopClient/GeneratedArtifacts
-**/*.DesktopClient/ModelManifest.xml
-**/*.Server/GeneratedArtifacts
-**/*.Server/ModelManifest.xml
-_Pvt_Extensions
-
-# Paket dependency manager
-.paket/paket.exe
-paket-files/
-
-# FAKE - F# Make
-.fake/
-
-# CodeRush personal settings
-.cr/personal
-
-# Python Tools for Visual Studio (PTVS)
-__pycache__/
-*.pyc
-
-# Cake - Uncomment if you are using it
-# tools/**
-# !tools/packages.config
-
-# Tabs Studio
-*.tss
-
-# Telerik's JustMock configuration file
-*.jmconfig
-
-# BizTalk build output
-*.btp.cs
-*.btm.cs
-*.odx.cs
-*.xsd.cs
-
-# OpenCover UI analysis results
-OpenCover/
-
-# Azure Stream Analytics local run output
-ASALocalRun/
-
-# MSBuild Binary and Structured Log
-*.binlog
-
-# NVidia Nsight GPU debugger configuration file
-*.nvuser
-
-# MFractors (Xamarin productivity tool) working folder
-.mfractor/
-
-# Local History for Visual Studio
-.localhistory/
-
-# BeatPulse healthcheck temp database
-healthchecksdb
-
-# Backup folder for Package Reference Convert tool in Visual Studio 2017
-MigrationBackup/
-
-# Ionide (cross platform F# VS Code tools) working folder
-.ionide/
-
-# Fody - auto-generated XML schema
-FodyWeavers.xsd
+/.vs/GitJW/v17/workspaceFileList.bin
+/.vs/NewEMIS/v17/fileList.bin
+/.vs/NewEMIS/config/applicationhost.config
+/.vs/slnx.sqlite
 /.vs
-**/Debug
+/EMiS.DataLogic/bin/Debug
+/EMiS.DataLogic/obj
+/EMIS.Entities/bin/Debug
+/EMIS.Entities/obj/Debug
+/EMIS.Entities/obj/Release/EMIS.Entities.csproj.AssemblyReference.cache
+/EMIS.Entities/obj/Release/.NETFramework,Version=v4.0.AssemblyAttributes.cs
+/EMIS.Entities.HRServices/bin/Debug
+/EMIS.Entities.HRServices/obj/Debug
+/EMIS.Entities.HRServices/obj/Release
+/EMIS.Entities.Log/bin/Debug
+/EMIS.Entities.Log/obj/Debug
+/EMiS.DataLogic
+/EMIS.Services
+/EMIS.ExtensionLogic.LCNX/obj
+/EMIS.ResourcesHBKD/obj
+/EMIS.ResourcesHBGD/obj
+/EMIS.ResourcesGZZY/obj
+/EMIS.ResourcesGZTY/obj
+/EMIS.ResourcesGZMS/obj
+/EMIS.ResourcesGDSS/obj
+/EMIS.ResourcesGDJS/obj
+/EMIS.ResourcesDGLG/obj
+/EMISOnline
+/EMIS.Web
+/EMIS.ViewModel
+/EMIS.Utility
+/EMIS.TestProject/obj/x86
+/EMIS.SSDataLogic
+/EMIS.ResourcesTest/obj
+/EMIS.ResourcesLCNX/obj
+/ServiceLogic
+/packages
+/Framework
+/学校扩展文件
+/广体终端机/Net版本/packages
+/督导评语7.16/App_Data

+ 10 - 0
EMIS.Entities.Log/EMIS.Entities.Log.Mapping.cs

@@ -0,0 +1,10 @@
+
+//------------------------------------------------------------------------------
+// <auto-generated>
+//    This code was generated from a template.
+//
+//    Manual changes to this file may cause unexpected behavior in your application.
+//    Manual changes to this file will be overwritten if the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+

+ 540 - 0
EMIS.Entities.Log/EMIS.Entities.Log.Mapping.tt

@@ -0,0 +1,540 @@
+<#@ template language="C#" debug="false" hostspecific="true"#>
+<#@ include file="EF.Utility.CS.ttinclude"#>
+<#@ assembly name="$(DevEnvDir)Microsoft.Data.Entity.Design.DatabaseGeneration.dll"#>
+<#@ import namespace="Microsoft.Data.Entity.Design.DatabaseGeneration" #>
+<#@ import namespace="System.Text"#>
+<#@ output extension=".cs"#><#
+CodeGenerationTools code = new CodeGenerationTools(this);
+CodeRegion region = new CodeRegion(this, 1);
+MetadataTools ef = new MetadataTools(this);
+string inputFile = @"EMISLogContext.edmx";
+
+var loadResult = LoadMetadata(inputFile);
+EdmItemCollection itemCollection = loadResult.EdmItems;
+var propertyToColumnMapping = loadResult.PropertyToColumnMapping;
+var manyToManyMappings = loadResult.ManyToManyMappings;
+var tphMappings = loadResult.TphMappings;
+string namespaceName = code.VsNamespaceSuggestion();
+string mapClassSuffix = "_Mapping";
+EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);
+WriteHeader(fileManager);
+
+foreach (EntityType entity in itemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
+{
+    fileManager.StartNewFile(entity.Name + mapClassSuffix + ".cs");
+    BeginNamespace(namespaceName, code);	
+#>
+#pragma warning disable 1573
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Data.Common;
+using System.Data.Entity;
+using System.Data.Entity.ModelConfiguration;
+using System.Data.Entity.Infrastructure;
+using System.ComponentModel.DataAnnotations.Schema;
+
+internal partial class <#=code.Escape(entity) + mapClassSuffix#><#=string.Format(" : EntityTypeConfiguration<{0}>", code.Escape(entity))#>
+{
+    public <#=code.Escape(entity) + mapClassSuffix#>()
+    {					
+<# 	
+	string hasKey;
+	if(entity.KeyMembers.Count<EdmMember>() == 1)
+		hasKey = string.Format(".HasKey(t => t.{0})", entity.KeyMembers[0].Name);
+   	else
+		hasKey = string.Format(".HasKey(t => new {{{0}}})", string.Join(", ", entity.KeyMembers.Select(m => "t." + m.Name)));
+			
+					
+#>
+		this<#=hasKey#>;		
+<#
+	if(tphMappings.Keys.Contains(entity))
+	{
+		foreach(KeyValuePair<EntityType, Dictionary<EdmProperty, string>> entityMapping in tphMappings[entity])
+		{
+#>
+		this.Map<<#=entityMapping.Key.Name #>>(m =>
+		{
+		<#
+		foreach(KeyValuePair<EdmProperty, string> propertyMapping in entityMapping.Value)
+		{
+			string val;
+			switch(propertyMapping.Key.TypeUsage.EdmType.BaseType.FullName)
+			{
+				case "Edm.String":
+					val="\""+propertyMapping.Value+"\"";
+					break;
+				default:
+					val=propertyMapping.Value;
+					break;
+			}
+			
+		#>	m.Requires("<#=propertyMapping.Key.Name#>").HasValue(<#=val#>);
+		<#
+		}
+		#>});
+<#
+		}
+	}
+	
+    var entityPropertyToColumnMapping = propertyToColumnMapping[entity];	
+#>
+		this.ToTable("<#=ToTable(entityPropertyToColumnMapping.Item1)#>");
+<# 
+	foreach (EdmProperty property in entity.Properties)
+    {
+		string generateOption = GetGenerationOption(property, entity);
+		string required = "";
+		string unicCode = "";
+		string fixedLength = "";
+		string maxLength = "";
+		PrimitiveType edmType = (PrimitiveType) property.TypeUsage.EdmType;
+		if(edmType.ClrEquivalentType == typeof(string) || edmType.ClrEquivalentType == typeof(byte[]))
+		{
+			if (!property.Nullable)
+                required = ".IsRequired()";            
+
+			Facet unicodeFacet = property.TypeUsage.Facets.SingleOrDefault(f => f.Name == "Unicode");
+			unicCode = unicodeFacet != null && unicodeFacet.Value != null && (!(bool)unicodeFacet.Value) ? ".IsUnicode(false)" : "";
+		
+			Facet fixedLengthFacet = property.TypeUsage.Facets.SingleOrDefault(f => f.Name == "FixedLength");
+			fixedLength = fixedLengthFacet != null && fixedLengthFacet.Value != null && ((bool)fixedLengthFacet.Value) ? ".IsFixedLength()" : "";
+		
+			Facet maxLengthFacet = property.TypeUsage.Facets.SingleOrDefault(f => f.Name == "MaxLength");
+			maxLength = (maxLengthFacet != null && maxLengthFacet.Value != null && !maxLengthFacet.IsUnbounded) ? string.Format(".HasMaxLength({0})", maxLengthFacet.Value) : "";
+		}
+		if(!entityPropertyToColumnMapping.Item2.Keys.Contains(property)) continue;
+    	string hasColumnName = string.Format(".HasColumnName(\"{0}\")", entityPropertyToColumnMapping.Item2[property].Name);
+#>
+		this.Property(t => t.<#= property.Name#>)<#=hasColumnName + generateOption + required + unicCode + fixedLength + maxLength #>;
+<# 
+    } 
+
+  	var navigationProperties = entity.NavigationProperties.Where(np => 
+			{
+				return ((np.DeclaringType == entity) && 
+					   ((AssociationType) np.RelationshipType).IsForeignKey) && 
+					   (((AssociationType) np.RelationshipType).ReferentialConstraints.Single<ReferentialConstraint>().ToRole == np.FromEndMember);
+			});
+	foreach(NavigationProperty navProperty in navigationProperties)
+	{
+		StringBuilder navPropBuilder = new StringBuilder();
+		NavigationProperty navPropertyBackReference = navProperty.ToEndMember.GetEntityType().NavigationProperties
+						.Where(npBack => npBack.RelationshipType == navProperty.RelationshipType && npBack != navProperty)
+						.Single();
+        AssociationType associationType = (AssociationType) navProperty.RelationshipType;
+        if (navProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.One)            
+            navPropBuilder.AppendFormat("this.HasRequired(t => t.{0})", code.Escape(navProperty));                            
+        else            
+            navPropBuilder.AppendFormat("this.HasOptional(t => t.{0})", code.Escape(navProperty));                
+        
+        if (navProperty.FromEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many)
+        {
+            navPropBuilder.AppendFormat(".WithMany(t => t.{0})", code.Escape(navPropertyBackReference));                
+            if (associationType.ReferentialConstraints.Single().ToProperties.Count == 1)                
+                navPropBuilder.AppendFormat(".HasForeignKey(d => d.{0})", associationType.ReferentialConstraints.Single().ToProperties.Single().Name);                    
+            else
+            	navPropBuilder.AppendFormat(".HasForeignKey(d => new {{{0}}})", string.Join(", ", associationType.ReferentialConstraints.Single().ToProperties.Select(p => "d." + p.Name)));                    
+        }
+        else
+        {
+            navPropBuilder.AppendFormat(".WithOptional(t => t.{0})", code.Escape(navPropertyBackReference));                
+        }
+#>
+		<#= navPropBuilder.ToString() #>;
+<# 
+		}
+		
+		var manyToMany = entity.NavigationProperties.Where(np =>
+				np.DeclaringType == entity 
+				&& np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many 
+				&& np.FromEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many 
+				&& np.RelationshipType.RelationshipEndMembers.First() == np.FromEndMember);
+		
+		var manyToManyBuilder = new StringBuilder();
+		
+		foreach (NavigationProperty navProperty in manyToMany)
+		{
+			var member = navProperty.ToEndMember.GetEntityType().NavigationProperties
+							.Single(nv => (nv.RelationshipType == navProperty.RelationshipType) && (nv != navProperty));
+			var relationshipType = (AssociationType) navProperty.RelationshipType;
+			Tuple<EntitySet, Dictionary<RelationshipEndMember, Dictionary<EdmMember, string>>> tuple; 
+			if(manyToManyMappings.TryGetValue(relationshipType, out tuple))
+			{
+				string middleTableName = this.ToTable(tuple.Item1);
+				
+				var leftType = (EntityType) navProperty.DeclaringType;
+				Dictionary<EdmMember, string> leftKeyMappings = tuple.Item2[navProperty.FromEndMember];
+				string leftColumns = string.Join(", ", leftType.KeyMembers.Select(m => "\"" + leftKeyMappings[m] + "\""));
+				
+				var rightType = (EntityType) member.DeclaringType;
+				Dictionary<EdmMember, string> rightKeyMappings = tuple.Item2[member.FromEndMember];
+				string rightColumns = string.Join(", ", rightType.KeyMembers.Select(m => "\"" + rightKeyMappings[m] + "\""));
+				
+#>
+		this.HasMany(t => t.<#= code.Escape(navProperty) #>).WithMany(t => t.<#= code.Escape(member) #>)
+			.Map(m => 
+			{
+				m.ToTable("<#= middleTableName #>");
+				m.MapLeftKey(<#= leftColumns #>);
+				m.MapRightKey(<#= rightColumns #>);
+			});
+<#
+			}
+		}
+#>
+	}
+}
+<#
+    EndNamespace(namespaceName);
+}
+#>
+
+<#
+
+if (!VerifyTypesAreCaseInsensitiveUnique(itemCollection))
+{
+    return "";
+}
+
+fileManager.Process();
+
+#>
+<#+
+string GetResourceString(string resourceName)
+{
+	if(_resourceManager2 == null)
+	{
+		_resourceManager2 = new System.Resources.ResourceManager("System.Data.Entity.Design", typeof(System.Data.Entity.Design.MetadataItemCollectionFactory).Assembly);
+	}
+	
+    return _resourceManager2.GetString(resourceName, null);
+}
+System.Resources.ResourceManager _resourceManager2;
+
+void WriteHeader(EntityFrameworkTemplateFileManager fileManager)
+{
+    fileManager.StartHeader();
+#>
+//------------------------------------------------------------------------------
+// <auto-generated>
+//    This code was generated from a template.
+//
+//    Manual changes to this file may cause unexpected behavior in your application.
+//    Manual changes to this file will be overwritten if the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+<#+
+    fileManager.EndBlock();
+}
+
+void BeginNamespace(string namespaceName, CodeGenerationTools code)
+{
+    CodeRegion region = new CodeRegion(this);
+    if (!String.IsNullOrEmpty(namespaceName))
+    {
+#>
+namespace <#=code.EscapeNamespace(namespaceName)#>
+{
+<#+
+        PushIndent(CodeRegion.GetIndent(1));
+    }
+}
+
+
+void EndNamespace(string namespaceName)
+{
+    if (!String.IsNullOrEmpty(namespaceName))
+    {
+        PopIndent();
+#>
+}
+<#+
+    }
+}
+string ToTable(EntitySet entitySet)
+{
+	var toTable = entitySet.Name;
+	//string schema = entitySet.GetSchemaName();
+	//if(!string.IsNullOrWhiteSpace(schema) && schema != "dbo")	
+	//	toTable += "\", \"" + schema;
+	return toTable;
+}
+
+bool VerifyTypesAreCaseInsensitiveUnique(EdmItemCollection itemCollection)
+{
+    var alreadySeen = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
+    foreach(var type in itemCollection.GetItems<StructuralType>())
+    {
+        if (!(type is EntityType || type is ComplexType))
+        {
+            continue;
+        }
+
+        if (alreadySeen.ContainsKey(type.FullName))
+        {
+            Error(String.Format(CultureInfo.CurrentCulture, "This template does not support types that differ only by case, the types {0} are not supported", type.FullName));
+            return false;
+        }
+        else
+        {
+            alreadySeen.Add(type.FullName, true);
+        }
+    }
+
+    return true;
+}
+
+string GetGenerationOption(EdmProperty property, EntityType entity)
+{
+	string result = "";
+	bool isPk = entity.KeyMembers.Contains(property);
+	MetadataProperty storeGeneratedPatternProperty = null;
+	string storeGeneratedPatternPropertyValue = "None";
+	
+	if(property.MetadataProperties.TryGetValue(MetadataConsts.EDM_ANNOTATION_09_02 + ":StoreGeneratedPattern", false, out storeGeneratedPatternProperty))	
+		storeGeneratedPatternPropertyValue = storeGeneratedPatternProperty.Value.ToString();		
+	
+	PrimitiveType edmType = (PrimitiveType) property.TypeUsage.EdmType; 
+	if (storeGeneratedPatternPropertyValue == "Computed")
+	{
+	    result = ".HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed)";
+	}
+	else if ((edmType.ClrEquivalentType == typeof(int)) || (edmType.ClrEquivalentType == typeof(short)) || (edmType.ClrEquivalentType == typeof(long)))
+	{
+	    if (isPk && (storeGeneratedPatternPropertyValue != "Identity"))
+	        result = ".HasDatabaseGeneratedOption(DatabaseGeneratedOption.None)";
+	    else if ((!isPk || (entity.KeyMembers.Count > 1)) && (storeGeneratedPatternPropertyValue == "Identity"))
+	        result = ".HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)";
+	}	
+	return result;    
+}
+
+MetadataLoadResult LoadMetadata(string inputFile)
+{       
+	var loader = new MetadataLoader(this);
+	bool loaded = false;
+	EdmItemCollection edmItemCollection = loader.CreateEdmItemCollection(inputFile);      
+	StoreItemCollection storeItemCollection = null;
+	if (loader.TryCreateStoreItemCollection(inputFile, out storeItemCollection))
+	{
+		StorageMappingItemCollection storageMappingItemCollection;
+		if (loader.TryCreateStorageMappingItemCollection(inputFile, edmItemCollection, storeItemCollection, out storageMappingItemCollection))
+			loaded = true;
+	}
+
+	if(loaded == false)
+		throw new Exception("Cannot load a metadata from the file " + inputFile);
+
+	var mappingMetadata = LoadMappingMetadata(inputFile);
+	var mappingNode		= mappingMetadata.Item1;
+	var nsmgr			= mappingMetadata.Item2;
+
+	var allEntitySets = storeItemCollection.GetAllEntitySets();		
+
+	return new MetadataLoadResult
+	       	{
+	       		EdmItems = edmItemCollection,
+	       		PropertyToColumnMapping = BuildEntityMappings(mappingNode, nsmgr, edmItemCollection.GetItems<EntityType>(), edmItemCollection.GetAllEntitySets(), allEntitySets),
+	       		ManyToManyMappings = BuildManyToManyMappings(mappingNode, nsmgr, edmItemCollection.GetAllAssociationSets(), allEntitySets),
+				TphMappings=BuildTPHMappings(mappingNode, nsmgr, edmItemCollection.GetItems<EntityType>(), edmItemCollection.GetAllEntitySets(), allEntitySets)
+	       	};
+}
+
+private Tuple<XmlNode, XmlNamespaceManager> LoadMappingMetadata(string inputFile)
+{
+	var xmlDoc = new XmlDocument();
+     xmlDoc.Load(Host.ResolvePath(inputFile));
+
+	 var schemaConstantsList = new SchemaConsts[]
+					{						
+						MetadataConsts.V2_SCHEMA_CONSTANTS,
+						MetadataConsts.V1_SCHEMA_CONSTANTS
+					};
+	foreach (var schemaConstants in schemaConstantsList)
+	{
+		var nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
+		nsmgr.AddNamespace("ef", schemaConstants.MslNamespace);
+		nsmgr.AddNamespace("edmx", schemaConstants.EdmxNamespace);
+		var mappingNode = xmlDoc.DocumentElement.SelectSingleNode("./*/edmx:Mappings", nsmgr);
+
+		if(mappingNode != null)
+			return Tuple.Create(mappingNode, nsmgr);
+	}     
+
+	throw new Exception(GetResourceString("Template_UnsupportedSchema"));
+}
+
+private Dictionary<EntityType, Dictionary<EntityType, Dictionary<EdmProperty, string>>> BuildTPHMappings(XmlNode mappingNode, XmlNamespaceManager nsmgr, IEnumerable<EntityType> entityTypes, IEnumerable<EntitySet> entitySets, IEnumerable<EntitySet> tableSets)
+{
+	var dictionary = new Dictionary<EntityType, Dictionary<EntityType, Dictionary<EdmProperty, string>>>();	
+	foreach (EntitySet set in entitySets)
+	{
+		XmlNodeList nodes = mappingNode.SelectNodes(string.Format(".//ef:EntitySetMapping[@Name=\"{0}\"]/ef:EntityTypeMapping/ef:MappingFragment", set.Name), nsmgr);
+		foreach(XmlNode node in nodes)
+		{
+			string typeName=node.ParentNode.Attributes["TypeName"].Value;
+			if(typeName.StartsWith("IsTypeOf("))
+				typeName=typeName.Substring("IsTypeOf(".Length, typeName.Length-"IsTypeOf()".Length);
+			EntityType type=entityTypes.Single(z=>z.FullName==typeName);
+			string tableName = node.Attributes["StoreEntitySet"].Value;
+			EntitySet set2 = tableSets.Single(entitySet => entitySet.Name == tableName);
+			var entityMap = new Dictionary<EdmProperty, string>();
+			
+			XmlNodeList propertyNodes = node.SelectNodes("./ef:Condition", nsmgr);
+			if(propertyNodes.Count==0) continue;
+			foreach(XmlNode propertyNode in propertyNodes)
+			{
+				string str = propertyNode.Attributes["ColumnName"].Value;
+				EdmProperty property2 = set2.ElementType.Properties[str];
+				string val=propertyNode.Attributes["Value"].Value;
+				entityMap.Add(property2, val);
+			}
+			EntityType baseType=(EntityType)(type.BaseType??type);
+			if(!dictionary.Keys.Contains(baseType))
+			{
+			var entityMappings=new Dictionary<EntityType, Dictionary<EdmProperty, string>>();
+			//entityMappings.Add(type,entityMap);
+			dictionary.Add(baseType, entityMappings);
+			}
+			dictionary[baseType].Add(type,entityMap);
+		}
+	}
+	return dictionary;
+}		
+
+private Dictionary<EntityType, Tuple<EntitySet, Dictionary<EdmProperty, EdmProperty>>> BuildEntityMappings(XmlNode mappingNode, XmlNamespaceManager nsmgr, IEnumerable<EntityType> entityTypes, IEnumerable<EntitySet> entitySets, IEnumerable<EntitySet> tableSets)
+{
+	var dictionary = new Dictionary<EntityType, Tuple<EntitySet, Dictionary<EdmProperty, EdmProperty>>>();
+
+	foreach (EntitySet set in entitySets)
+	{
+		XmlNodeList nodes = mappingNode.SelectNodes(string.Format(".//ef:EntitySetMapping[@Name=\"{0}\"]/ef:EntityTypeMapping/ef:MappingFragment", set.Name), nsmgr);
+		foreach(XmlNode node in nodes)
+		{
+			string typeName=node.ParentNode.Attributes["TypeName"].Value;
+			if(typeName.StartsWith("IsTypeOf("))
+				typeName=typeName.Substring("IsTypeOf(".Length, typeName.Length-"IsTypeOf()".Length);
+			EntityType type=entityTypes.Single(z=>z.FullName==typeName);
+			string tableName = node.Attributes["StoreEntitySet"].Value;
+			EntitySet set2 = tableSets.Single(entitySet => entitySet.Name == tableName);
+			var entityMap = new Dictionary<EdmProperty, EdmProperty>();
+			foreach (EdmProperty property in type.Properties)
+			{
+				XmlNode propertyNode = node.SelectSingleNode(string.Format("./ef:ScalarProperty[@Name=\"{0}\"]", property.Name), nsmgr);
+				if(propertyNode == null) continue;
+				string str = propertyNode.Attributes["ColumnName"].Value;
+				EdmProperty property2 = set2.ElementType.Properties[str];
+				entityMap.Add(property, property2);
+			}
+			dictionary.Add(type, Tuple.Create(set2, entityMap));
+		}
+	}
+	return dictionary;
+}
+
+Dictionary<AssociationType, Tuple<EntitySet, Dictionary<RelationshipEndMember, Dictionary<EdmMember, string>>>> BuildManyToManyMappings(XmlNode mappingNode, XmlNamespaceManager nsmgr, IEnumerable<AssociationSet> associationSets, IEnumerable<EntitySet> tableSets)
+{
+	var dictionary = new Dictionary<AssociationType, Tuple<EntitySet, Dictionary<RelationshipEndMember, Dictionary<EdmMember, string>>>>();
+	foreach (AssociationSet associationSet in associationSets.Where(set => set.ElementType.IsManyToMany()))
+	{
+		
+		XmlNode node = mappingNode.SelectSingleNode(string.Format("//ef:AssociationSetMapping[@Name=\"{0}\"]", associationSet.Name), nsmgr);
+		string tableName = node.Attributes["StoreEntitySet"].Value;
+		EntitySet entitySet = tableSets.Single(s => s.Name == tableName);
+		
+		var relationEndMap = new Dictionary<RelationshipEndMember, Dictionary<EdmMember, string>>();
+		foreach (AssociationSetEnd end in associationSet.AssociationSetEnds)
+		{
+			var map = new Dictionary<EdmMember, string>();
+			foreach (XmlNode endProperty in node.SelectSingleNode(string.Format("./ef:EndProperty[@Name=\"{0}\"]", end.Name), nsmgr).ChildNodes)
+			{
+				string str = endProperty.Attributes["Name"].Value;
+				EdmProperty key = end.EntitySet.ElementType.Properties[str];
+				string str2 = endProperty.Attributes["ColumnName"].Value;
+				map.Add(key, str2);
+			}
+			relationEndMap.Add(end.CorrespondingAssociationEndMember, map);
+		}
+		dictionary.Add(associationSet.ElementType, Tuple.Create(entitySet, relationEndMap));
+	}
+	return dictionary;
+}
+
+public class MetadataLoadResult
+{
+	public EdmItemCollection EdmItems { get; set; }
+	public Dictionary<EntityType, Tuple<EntitySet, Dictionary<EdmProperty, EdmProperty>>> PropertyToColumnMapping { get; set; }
+	public Dictionary<AssociationType, Tuple<EntitySet, Dictionary<RelationshipEndMember, Dictionary<EdmMember, string>>>> ManyToManyMappings { get; set; }
+	public Dictionary<EntityType, Dictionary<EntityType, Dictionary<EdmProperty, string>>> TphMappings { get; set; }
+}
+
+/// <summary>
+/// Responsible for encapsulating the constants defined in Metadata
+/// </summary>
+public static class MetadataConsts
+{
+    public const string CSDL_EXTENSION = ".csdl";
+
+    public const string CSDL_EDMX_SECTION_NAME = "ConceptualModels";
+    public const string CSDL_ROOT_ELEMENT_NAME = "Schema";
+    public const string EDM_ANNOTATION_09_02 = "http://schemas.microsoft.com/ado/2009/02/edm/annotation";
+
+    public const string SSDL_EXTENSION = ".ssdl";
+
+    public const string SSDL_EDMX_SECTION_NAME = "StorageModels";
+    public const string SSDL_ROOT_ELEMENT_NAME = "Schema";
+
+    public const string MSL_EXTENSION = ".msl";
+
+    public const string MSL_EDMX_SECTION_NAME = "Mappings";
+    public const string MSL_ROOT_ELEMENT_NAME = "Mapping";
+
+    public const string TT_TEMPLATE_NAME = "TemplateName";
+    public const string TT_TEMPLATE_VERSION = "TemplateVersion";
+    public const string TT_MINIMUM_ENTITY_FRAMEWORK_VERSION = "MinimumEntityFrameworkVersion";
+
+    public const string DEFAULT_TEMPLATE_VERSION = "4.0";
+
+    public static readonly SchemaConsts V1_SCHEMA_CONSTANTS = new SchemaConsts(
+        "http://schemas.microsoft.com/ado/2007/06/edmx",
+        "http://schemas.microsoft.com/ado/2006/04/edm",
+        "http://schemas.microsoft.com/ado/2006/04/edm/ssdl",
+        "urn:schemas-microsoft-com:windows:storage:mapping:CS",
+        new Version("3.5"));
+
+    public static readonly SchemaConsts V2_SCHEMA_CONSTANTS = new SchemaConsts(
+        "http://schemas.microsoft.com/ado/2008/10/edmx",
+        "http://schemas.microsoft.com/ado/2008/09/edm",
+        "http://schemas.microsoft.com/ado/2009/02/edm/ssdl",
+        "http://schemas.microsoft.com/ado/2008/09/mapping/cs",
+        new Version("4.0"));
+
+    public static readonly SchemaConsts V3_SCHEMA_CONSTANTS = new SchemaConsts(
+        "http://schemas.microsoft.com/ado/2009/11/edmx",
+        "http://schemas.microsoft.com/ado/2009/11/edm",
+        "http://schemas.microsoft.com/ado/2009/11/edm/ssdl",
+        "http://schemas.microsoft.com/ado/2009/11/mapping/cs",
+        new Version("4.5"));
+}
+
+public struct SchemaConsts
+{
+    public SchemaConsts(string edmxNamespace, string csdlNamespace, string ssdlNamespace, string mslNamespace, Version minimumTemplateVersion) : this()
+    {
+        EdmxNamespace = edmxNamespace;
+        CsdlNamespace = csdlNamespace;
+        SsdlNamespace = ssdlNamespace;
+        MslNamespace = mslNamespace;
+        MinimumTemplateVersion = minimumTemplateVersion;
+    }
+
+   public string EdmxNamespace { get; private set; }
+    public string CsdlNamespace { get; private set; }
+    public string SsdlNamespace { get; private set; }
+    public string MslNamespace { get; private set; }
+    public Version MinimumTemplateVersion { get; private set; }
+}
+#>

+ 311 - 0
EMIS.Entities.Log/EMIS.Entities.Log.tt

@@ -0,0 +1,311 @@
+<#@ template language="C#" debug="false" hostspecific="true"#>
+<#@ include file="EF.Utility.CS.ttinclude"#><#@
+ output extension=".cs"#><#
+
+CodeGenerationTools code = new CodeGenerationTools(this);
+MetadataLoader loader = new MetadataLoader(this);
+CodeRegion region = new CodeRegion(this, 1);
+MetadataTools ef = new MetadataTools(this);
+
+string inputFile = @"EMISLogContext.edmx";
+EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
+string namespaceName = code.VsNamespaceSuggestion();
+
+EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);
+WriteHeader(fileManager);
+
+string summary=string.Empty;
+
+foreach (EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
+{
+    fileManager.StartNewFile(entity.Name + ".cs");
+    BeginNamespace(namespaceName, code);
+	if(entity.Documentation !=null && entity.Documentation.Summary!=null)
+       summary=entity.Documentation.Summary;
+    else
+       summary=entity.Name;	
+#>
+#pragma warning disable 1573
+using System;
+using System.Collections.Generic;
+
+/// <summary>
+/// <#=summary#>
+/// </summary>
+<#=Accessibility.ForType(entity)#> <#=code.SpaceAfter(code.AbstractOption(entity))#>partial class <#=code.Escape(entity)#><#=code.StringBefore(" : ", code.Escape(entity.BaseType))#>
+{
+<#
+    
+	var propertiesWithDefaultValues = entity.Properties.Where(p => p.TypeUsage.EdmType is PrimitiveType && p.DeclaringType == entity && p.DefaultValue != null);
+    var collectionNavigationProperties = entity.NavigationProperties.Where(np => np.DeclaringType == entity && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
+    var complexProperties = entity.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == entity);
+	
+    if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any())
+    {
+#>
+    public <#=code.Escape(entity)#>()
+    {
+<#
+        foreach (var edmProperty in propertiesWithDefaultValues)
+        {
+#>
+        this.<#=code.Escape(edmProperty)#> = <#=code.CreateLiteral(edmProperty.DefaultValue)#>;
+<#
+        }
+
+        foreach (var navigationProperty in collectionNavigationProperties)
+        {
+#>
+        this.<#=code.Escape(navigationProperty)#> = new HashSet<<#=code.Escape(navigationProperty.ToEndMember.GetEntityType())#>>();
+<#
+        }
+
+        foreach (var complexProperty in complexProperties)
+        {
+#>
+        this.<#=code.Escape(complexProperty)#> = new <#=code.Escape(complexProperty.TypeUsage)#>();
+<#
+        }
+#>
+    }
+
+<#
+    }
+
+    var primitiveProperties = entity.Properties.Where(p => p.TypeUsage.EdmType is PrimitiveType && p.DeclaringType == entity);
+    if (primitiveProperties.Any())
+    {
+        foreach (var edmProperty in primitiveProperties)
+        {
+            WriteProperty(code, edmProperty);
+        }
+    }
+
+    if (complexProperties.Any())
+    {
+#>
+
+<#
+        foreach(var complexProperty in complexProperties)
+        {
+            WriteProperty(code, complexProperty);
+        }
+    }
+
+    var navigationProperties = entity.NavigationProperties.Where(np => np.DeclaringType == entity);
+    if (navigationProperties.Any())
+    {
+#>
+
+<#
+        foreach (var navigationProperty in navigationProperties)
+        {
+            WriteNavigationProperty(code, navigationProperty);
+        }
+    }
+#>
+}
+<#
+    EndNamespace(namespaceName);
+}
+
+foreach (var complex in ItemCollection.GetItems<ComplexType>().OrderBy(e => e.Name))
+{
+    fileManager.StartNewFile(complex.Name + ".cs");
+    BeginNamespace(namespaceName, code);
+#>
+using System;
+
+<#=Accessibility.ForType(complex)#> partial class <#=code.Escape(complex)#>
+{
+<#
+    var complexProperties = complex.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == complex);
+    var propertiesWithDefaultValues = complex.Properties.Where(p => p.TypeUsage.EdmType is PrimitiveType && p.DeclaringType == complex && p.DefaultValue != null);
+
+    if (propertiesWithDefaultValues.Any() || complexProperties.Any())
+    {
+#>
+    public <#=code.Escape(complex)#>()
+    {
+<#
+        foreach (var edmProperty in propertiesWithDefaultValues)
+        {
+#>
+        this.<#=code.Escape(edmProperty)#> = <#=code.CreateLiteral(edmProperty.DefaultValue)#>;
+<#
+        }
+
+        foreach (var complexProperty in complexProperties)
+        {
+#>
+        this.<#=code.Escape(complexProperty)#> = new <#=code.Escape(complexProperty.TypeUsage)#>();
+<#
+        }
+#>
+    }
+
+<#
+    }
+
+    var primitiveProperties = complex.Properties.Where(p => p.TypeUsage.EdmType is PrimitiveType && p.DeclaringType == complex);
+    if (primitiveProperties.Any())
+    {
+        foreach(var edmProperty in primitiveProperties)
+        {
+            WriteProperty(code, edmProperty);
+        }
+    }
+
+    if (complexProperties.Any())
+    {
+#>
+
+<#
+        foreach(var edmProperty in complexProperties)
+        {
+            WriteProperty(code, edmProperty);
+        }
+    }
+#>
+}
+<#
+    EndNamespace(namespaceName);
+}
+
+if (!VerifyTypesAreCaseInsensitiveUnique(ItemCollection))
+{
+    return "";
+}
+
+fileManager.Process();
+
+#>
+<#+
+void WriteHeader(EntityFrameworkTemplateFileManager fileManager)
+{
+    fileManager.StartHeader();
+#>
+//------------------------------------------------------------------------------
+// <auto-generated>
+//    This code was generated from a template.
+//
+//    Manual changes to this file may cause unexpected behavior in your application.
+//    Manual changes to this file will be overwritten if the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+<#+
+    fileManager.EndBlock();
+}
+
+void BeginNamespace(string namespaceName, CodeGenerationTools code)
+{
+    CodeRegion region = new CodeRegion(this);
+    if (!String.IsNullOrEmpty(namespaceName))
+    {
+#>
+namespace <#=code.EscapeNamespace(namespaceName)#>
+{
+<#+
+        PushIndent(CodeRegion.GetIndent(1));
+    }
+}
+
+
+void EndNamespace(string namespaceName)
+{
+    if (!String.IsNullOrEmpty(namespaceName))
+    {
+        PopIndent();
+#>
+}
+<#+
+    }
+}
+
+void WriteProperty(CodeGenerationTools code, EdmProperty edmProperty)
+{
+	if (edmProperty.Documentation != null && edmProperty.Documentation.Summary != null)
+    { 
+        WriteProperty(Accessibility.ForProperty(edmProperty),
+                      code.Escape(edmProperty.Documentation.Summary),
+                      code.Escape(edmProperty.TypeUsage),
+                      code.Escape(edmProperty),
+                      code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
+                      code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
+    }
+    else
+    {
+        WriteProperty(Accessibility.ForProperty(edmProperty),
+                      code.Escape(edmProperty.Name),
+                      code.Escape(edmProperty.TypeUsage),
+                      code.Escape(edmProperty),
+                      code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
+                      code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
+    }
+}
+
+void WriteNavigationProperty(CodeGenerationTools code, NavigationProperty navigationProperty)
+{
+    var endType = code.Escape(navigationProperty.ToEndMember.GetEntityType());
+
+	if (navigationProperty.Documentation != null && navigationProperty.Documentation.Summary != null)
+    { 
+		WriteProperty(PropertyVirtualModifier(Accessibility.ForProperty(navigationProperty)),
+					  code.Escape(navigationProperty.Documentation.Summary),
+					  navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("HashSet<" + endType + ">") : endType,
+					  code.Escape(navigationProperty),
+					  code.SpaceAfter(Accessibility.ForGetter(navigationProperty)),
+					  code.SpaceAfter(Accessibility.ForSetter(navigationProperty)));
+    }
+    else
+    {
+		WriteProperty(PropertyVirtualModifier(Accessibility.ForProperty(navigationProperty)),
+					code.Escape(navigationProperty.Name),
+					navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("HashSet<" + endType + ">") : endType,
+					code.Escape(navigationProperty),
+					code.SpaceAfter(Accessibility.ForGetter(navigationProperty)),
+					code.SpaceAfter(Accessibility.ForSetter(navigationProperty)));
+    }
+
+}
+
+void WriteProperty(string accessibility, string summary, string type, string name, string getterAccessibility, string setterAccessibility)
+{
+#>
+	/// <summary>
+    /// <#=summary#>
+    /// </summary>
+    <#=accessibility#> <#=type#> <#=name#> { <#=getterAccessibility#>get; <#=setterAccessibility#>set; }
+<#+
+}
+
+string PropertyVirtualModifier(string accessibility)
+{
+    return accessibility + (accessibility != "private" ? " virtual" : "");
+}
+
+bool VerifyTypesAreCaseInsensitiveUnique(EdmItemCollection itemCollection)
+{
+    var alreadySeen = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
+    foreach(var type in itemCollection.GetItems<StructuralType>())
+    {
+        if (!(type is EntityType || type is ComplexType))
+        {
+            continue;
+        }
+
+        if (alreadySeen.ContainsKey(type.FullName))
+        {
+            Error(String.Format(CultureInfo.CurrentCulture, "This template does not support types that differ only by case, the types {0} are not supported", type.FullName));
+            return false;
+        }
+        else
+        {
+            alreadySeen.Add(type.FullName, true);
+        }
+    }
+
+    return true;
+}
+#>

+ 4 - 0
EMIS.Entities.Log/EMISLogContext.Designer.cs

@@ -0,0 +1,4 @@
+// 模型“D:\开发项目\教务管理系统\源代码New\EMIS.Entities.Log\EMISLogContext.edmx”的默认代码生成功能已禁用。
+// 要启用默认代码生成功能,请将“代码生成策略”设计器属性的值
+// 更改为另一值。当在设计器中打开该模型时,此属性会出现在
+// “属性”窗口中。

+ 155 - 0
EMIS.Entities.Log/EMISLogContext.edmx

@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="utf-8"?>
+<edmx:Edmx Version="2.0" xmlns:edmx="http://schemas.microsoft.com/ado/2008/10/edmx">
+  <!-- EF Runtime content -->
+  <edmx:Runtime>
+    <!-- SSDL content -->
+    <edmx:StorageModels>
+      <Schema Namespace="EMIS.Entities.Log.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2008" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2009/02/edm/ssdl">
+        <EntityContainer Name="EMISEntitiesLogStoreContainer">
+          <EntitySet Name="Log_Operate" EntityType="EMIS.Entities.Log.Store.Log_Operate" store:Type="Tables" Schema="dbo" />
+          <EntitySet Name="VW_Sys_User" EntityType="EMIS.Entities.Log.Store.VW_Sys_User" store:Type="Views" store:Schema="dbo" store:Name="VW_Sys_User">
+            <DefiningQuery>SELECT 
+      [VW_Sys_User].[UserID] AS [UserID], 
+      [VW_Sys_User].[LoginID] AS [LoginID], 
+      [VW_Sys_User].[Password] AS [Password], 
+      [VW_Sys_User].[Name] AS [Name], 
+      [VW_Sys_User].[RecordStatus] AS [RecordStatus], 
+      [VW_Sys_User].[CreateUserID] AS [CreateUserID], 
+      [VW_Sys_User].[CreateTime] AS [CreateTime], 
+      [VW_Sys_User].[ModifyUserID] AS [ModifyUserID], 
+      [VW_Sys_User].[ModifyTime] AS [ModifyTime]
+      FROM [dbo].[VW_Sys_User] AS [VW_Sys_User]</DefiningQuery>
+          </EntitySet>
+        </EntityContainer>
+        <EntityType Name="Log_Operate">
+          <Key>
+            <PropertyRef Name="OperateID" />
+          </Key>
+          <Property Name="OperateID" Type="uniqueidentifier" Nullable="false" />
+          <Property Name="UserID" Type="uniqueidentifier" />
+          <Property Name="IP" Type="varchar" MaxLength="50" />
+          <Property Name="TableName" Type="varchar" MaxLength="50" />
+          <Property Name="SourceUrl" Type="varchar" MaxLength="500" />
+          <Property Name="Operate" Type="nvarchar" MaxLength="50" />
+          <Property Name="Detail" Type="nvarchar(max)" />
+          <Property Name="IsSuccess" Type="bit" />
+          <Property Name="OperateTime" Type="datetime" />
+        </EntityType>
+        <!--生成过程中发现错误:
+      警告 6002: 表/视图“EMISNewLog.dbo.VW_Sys_User”未定义主键。已推断出该键,并将定义创建为只读的表/视图。
+      -->
+        <EntityType Name="VW_Sys_User">
+          <Key>
+            <PropertyRef Name="UserID" />
+          </Key>
+          <Property Name="UserID" Type="uniqueidentifier" Nullable="false" />
+          <Property Name="LoginID" Type="varchar" MaxLength="50" />
+          <Property Name="Password" Type="varchar" MaxLength="50" />
+          <Property Name="Name" Type="nvarchar" MaxLength="50" />
+          <Property Name="RecordStatus" Type="int" />
+          <Property Name="CreateUserID" Type="uniqueidentifier" />
+          <Property Name="CreateTime" Type="datetime" />
+          <Property Name="ModifyUserID" Type="uniqueidentifier" />
+          <Property Name="ModifyTime" Type="datetime" />
+        </EntityType>
+      </Schema>
+    </edmx:StorageModels>
+    <!-- CSDL content -->
+    <edmx:ConceptualModels>
+      <Schema Namespace="EMIS.Entities.Log" Alias="Self" xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
+        <EntityContainer Name="EMISNewLogContext" annotation:LazyLoadingEnabled="true">
+          <EntitySet Name="Log_Operate" EntityType="EMIS.Entities.Log.Log_Operate" />
+          <EntitySet Name="VW_Sys_User" EntityType="EMIS.Entities.Log.VW_Sys_User" />
+        </EntityContainer>
+        <EntityType Name="Log_Operate">
+          <Key>
+            <PropertyRef Name="OperateID" />
+          </Key>
+          <Property Name="OperateID" Type="Guid" Nullable="false" />
+          <Property Name="UserID" Type="Guid" />
+          <Property Name="IP" Type="String" MaxLength="50" Unicode="false" FixedLength="false" />
+          <Property Name="TableName" Type="String" MaxLength="50" Unicode="false" FixedLength="false" />
+          <Property Name="SourceUrl" Type="String" MaxLength="2000" Unicode="false" FixedLength="false" />
+          <Property Name="Operate" Type="String" MaxLength="50" Unicode="true" FixedLength="false" />
+          <Property Name="Detail" Type="String" MaxLength="Max" Unicode="true" FixedLength="false" />
+          <Property Name="IsSuccess" Type="Boolean" />
+          <Property Name="OperateTime" Type="DateTime" />
+        </EntityType>
+        <EntityType Name="VW_Sys_User">
+          <Key>
+            <PropertyRef Name="UserID" />
+          </Key>
+          <Property Name="UserID" Type="Guid" Nullable="false" />
+          <Property Name="LoginID" Type="String" MaxLength="50" Unicode="false" FixedLength="false" />
+          <Property Name="Password" Type="String" MaxLength="50" Unicode="false" FixedLength="false" />
+          <Property Name="Name" Type="String" MaxLength="50" Unicode="true" FixedLength="false" />
+          <Property Name="RecordStatus" Type="Int32" />
+          <Property Name="CreateUserID" Type="Guid" />
+          <Property Name="CreateTime" Type="DateTime" />
+          <Property Name="ModifyUserID" Type="Guid" />
+          <Property Name="ModifyTime" Type="DateTime" />
+        </EntityType>
+      </Schema>
+    </edmx:ConceptualModels>
+    <!-- C-S mapping content -->
+    <edmx:Mappings>
+      <Mapping Space="C-S" xmlns="http://schemas.microsoft.com/ado/2008/09/mapping/cs">
+        <EntityContainerMapping StorageEntityContainer="EMISEntitiesLogStoreContainer" CdmEntityContainer="EMISNewLogContext">
+          <EntitySetMapping Name="Log_Operate">
+            <EntityTypeMapping TypeName="EMIS.Entities.Log.Log_Operate">
+              <MappingFragment StoreEntitySet="Log_Operate">
+                <ScalarProperty Name="OperateID" ColumnName="OperateID" />
+                <ScalarProperty Name="UserID" ColumnName="UserID" />
+                <ScalarProperty Name="IP" ColumnName="IP" />
+                <ScalarProperty Name="TableName" ColumnName="TableName" />
+                <ScalarProperty Name="SourceUrl" ColumnName="SourceUrl" />
+                <ScalarProperty Name="Operate" ColumnName="Operate" />
+                <ScalarProperty Name="Detail" ColumnName="Detail" />
+                <ScalarProperty Name="IsSuccess" ColumnName="IsSuccess" />
+                <ScalarProperty Name="OperateTime" ColumnName="OperateTime" />
+              </MappingFragment>
+            </EntityTypeMapping>
+          </EntitySetMapping>
+          <EntitySetMapping Name="VW_Sys_User">
+            <EntityTypeMapping TypeName="EMIS.Entities.Log.VW_Sys_User">
+              <MappingFragment StoreEntitySet="VW_Sys_User">
+                <ScalarProperty Name="UserID" ColumnName="UserID" />
+                <ScalarProperty Name="LoginID" ColumnName="LoginID" />
+                <ScalarProperty Name="Password" ColumnName="Password" />
+                <ScalarProperty Name="Name" ColumnName="Name" />
+                <ScalarProperty Name="RecordStatus" ColumnName="RecordStatus" />
+                <ScalarProperty Name="CreateUserID" ColumnName="CreateUserID" />
+                <ScalarProperty Name="CreateTime" ColumnName="CreateTime" />
+                <ScalarProperty Name="ModifyUserID" ColumnName="ModifyUserID" />
+                <ScalarProperty Name="ModifyTime" ColumnName="ModifyTime" />
+              </MappingFragment>
+            </EntityTypeMapping>
+          </EntitySetMapping>
+        </EntityContainerMapping>
+      </Mapping>
+    </edmx:Mappings>
+  </edmx:Runtime>
+  <!-- EF Designer content (DO NOT EDIT MANUALLY BELOW HERE) -->
+  <Designer xmlns="http://schemas.microsoft.com/ado/2008/10/edmx">
+    <Connection>
+      <DesignerInfoPropertySet>
+        <DesignerProperty Name="MetadataArtifactProcessing" Value="EmbedInOutputAssembly" />
+      </DesignerInfoPropertySet>
+    </Connection>
+    <Options>
+      <DesignerInfoPropertySet>
+        <DesignerProperty Name="ValidateOnBuild" Value="true" />
+        <DesignerProperty Name="EnablePluralization" Value="False" />
+        <DesignerProperty Name="IncludeForeignKeysInModel" Value="True" />
+        <DesignerProperty Name="CodeGenerationStrategy" Value="无" />
+      </DesignerInfoPropertySet>
+    </Options>
+    <!-- Diagram content (shape and connector positions) -->
+    <Diagrams>
+      <Diagram Name="EMISLogContext">
+        <EntityTypeShape EntityType="EMIS.Entities.Log.Log_Operate" Width="1.5" PointX="0.75" PointY="0.75" Height="2.6594042968749996" IsExpanded="true" />
+        <EntityTypeShape EntityType="EMIS.Entities.Log.VW_Sys_User" Width="1.5" PointX="2.75" PointY="0.75" Height="2.6594042968749996" IsExpanded="true" />
+      </Diagram>
+    </Diagrams>
+  </Designer>
+</edmx:Edmx>

+ 58 - 0
EMIS.Entities.Log/Log_Operate.cs

@@ -0,0 +1,58 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//    This code was generated from a template.
+//
+//    Manual changes to this file may cause unexpected behavior in your application.
+//    Manual changes to this file will be overwritten if the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace EMIS.Entities.Log
+{
+    #pragma warning disable 1573
+    using System;
+    using System.Collections.Generic;
+    
+    /// <summary>
+    /// Log_Operate
+    /// </summary>
+    public partial class Log_Operate
+    {
+    	/// <summary>
+        /// OperateID
+        /// </summary>
+        public System.Guid OperateID { get; set; }
+    	/// <summary>
+        /// UserID
+        /// </summary>
+        public Nullable<System.Guid> UserID { get; set; }
+    	/// <summary>
+        /// IP
+        /// </summary>
+        public string IP { get; set; }
+    	/// <summary>
+        /// TableName
+        /// </summary>
+        public string TableName { get; set; }
+    	/// <summary>
+        /// SourceUrl
+        /// </summary>
+        public string SourceUrl { get; set; }
+    	/// <summary>
+        /// Operate
+        /// </summary>
+        public string Operate { get; set; }
+    	/// <summary>
+        /// Detail
+        /// </summary>
+        public string Detail { get; set; }
+    	/// <summary>
+        /// IsSuccess
+        /// </summary>
+        public Nullable<bool> IsSuccess { get; set; }
+    	/// <summary>
+        /// OperateTime
+        /// </summary>
+        public Nullable<System.DateTime> OperateTime { get; set; }
+    }
+}

+ 39 - 0
EMIS.Entities.Log/Log_Operate_Mapping.cs

@@ -0,0 +1,39 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//    This code was generated from a template.
+//
+//    Manual changes to this file may cause unexpected behavior in your application.
+//    Manual changes to this file will be overwritten if the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace EMIS.Entities.Log
+{
+    #pragma warning disable 1573
+    using System;
+    using System.Collections.Generic;
+    using System.ComponentModel.DataAnnotations;
+    using System.Data.Common;
+    using System.Data.Entity;
+    using System.Data.Entity.ModelConfiguration;
+    using System.Data.Entity.Infrastructure;
+    using System.ComponentModel.DataAnnotations.Schema;
+    
+    internal partial class Log_Operate_Mapping : EntityTypeConfiguration<Log_Operate>
+    {
+        public Log_Operate_Mapping()
+        {					
+    		this.HasKey(t => t.OperateID);		
+    		this.ToTable("Log_Operate");
+    		this.Property(t => t.OperateID).HasColumnName("OperateID");
+    		this.Property(t => t.UserID).HasColumnName("UserID");
+    		this.Property(t => t.IP).HasColumnName("IP").IsUnicode(false).HasMaxLength(50);
+    		this.Property(t => t.TableName).HasColumnName("TableName").IsUnicode(false).HasMaxLength(50);
+    		this.Property(t => t.SourceUrl).HasColumnName("SourceUrl").IsUnicode(false).HasMaxLength(2000);
+    		this.Property(t => t.Operate).HasColumnName("Operate").HasMaxLength(50);
+    		this.Property(t => t.Detail).HasColumnName("Detail");
+    		this.Property(t => t.IsSuccess).HasColumnName("IsSuccess");
+    		this.Property(t => t.OperateTime).HasColumnName("OperateTime");
+    	}
+    }
+}

+ 36 - 0
EMIS.Entities.Log/Properties/AssemblyInfo.cs

@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的常规信息通过以下
+// 特性集控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("EMIS.Entities.Log")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("EMIS.Entities.Log")]
+[assembly: AssemblyCopyright("Copyright ©  2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 使此程序集中的类型
+// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
+// 则将该类型上的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+[assembly: Guid("936d862a-becc-456d-9ea3-d7272e1fec1f")]
+
+// 程序集的版本信息由下面四个值组成:
+//
+//      主版本
+//      次版本 
+//      内部版本号
+//      修订号
+//
+// 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值,
+// 方法是按如下所示使用“*”:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 44 - 0
EMIS.Entities.Log/TableKey.cs

@@ -0,0 +1,44 @@
+
+//------------------------------------------------------------------------------
+// <auto-generated>
+//    This code was generated from a template.
+//
+//    Manual changes to this file may cause unexpected behavior in your application.
+//    Manual changes to this file will be overwritten if the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+
+using System.Collections.Generic;
+namespace EMIS.Entities.Log
+{
+	public class TableKeyDictionary
+	{
+        private static Dictionary<string, string> items;
+        public static Dictionary<string, string> Items
+        {
+            get { return items; }
+        }
+
+		static TableKeyDictionary()
+        {
+			items = new Dictionary<string, string>();
+			items.Add("Log_Operate", "OperateID");
+			items.Add("VW_Sys_User", "UserID");
+		}
+
+		public static string GetKeyName<TEntity>(TEntity entity)
+		{
+			string tableName = typeof(TEntity).Name;
+
+			return items[tableName];
+		}
+
+		public static string GetKeyName<TEntity>()
+		{
+			string tableName = typeof(TEntity).Name;
+
+			return items[tableName];
+		}
+	}
+}

+ 396 - 0
EMIS.Entities.Log/TableKey.tt

@@ -0,0 +1,396 @@
+<#@ template language="C#" debug="false" hostspecific="true"#>
+<#@ include file="EF.Utility.CS.ttinclude"#>
+<#@ assembly name="$(DevEnvDir)Microsoft.Data.Entity.Design.DatabaseGeneration.dll"#>
+<#@ import namespace="Microsoft.Data.Entity.Design.DatabaseGeneration" #>
+<#@ import namespace="System.Text"#>
+<#@ output extension=".cs"#><#
+CodeGenerationTools code = new CodeGenerationTools(this);
+CodeRegion region = new CodeRegion(this, 1);
+MetadataTools ef = new MetadataTools(this);
+string inputFile = @"EMISLogContext.edmx";
+
+var loadResult = LoadMetadata(inputFile);
+EdmItemCollection itemCollection = loadResult.EdmItems;
+var propertyToColumnMapping = loadResult.PropertyToColumnMapping;
+var manyToManyMappings = loadResult.ManyToManyMappings;
+var tphMappings = loadResult.TphMappings;
+string namespaceName = code.VsNamespaceSuggestion();
+string mapClassSuffix = "_Mapping";
+EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);
+WriteHeader(fileManager);#>
+
+using System.Collections.Generic;
+namespace EMIS.Entities.Log
+{
+	public class TableKeyDictionary
+	{
+        private static Dictionary<string, string> items;
+        public static Dictionary<string, string> Items
+        {
+            get { return items; }
+        }
+
+		static TableKeyDictionary()
+        {
+			items = new Dictionary<string, string>();
+<#foreach (EntityType entity in itemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
+{
+	string hasKey;
+	hasKey = string.Format("items.Add(\"{0}\", \"{1}\");", entity.Name, entity.KeyMembers[0].Name);#>
+			<#=hasKey#>
+<#}
+#>
+		}
+
+		public static string GetKeyName<TEntity>(TEntity entity)
+		{
+			string tableName = typeof(TEntity).Name;
+
+			return items[tableName];
+		}
+
+		public static string GetKeyName<TEntity>()
+		{
+			string tableName = typeof(TEntity).Name;
+
+			return items[tableName];
+		}
+	}
+}
+<#+
+string GetResourceString(string resourceName)
+{
+	if(_resourceManager2 == null)
+	{
+		_resourceManager2 = new System.Resources.ResourceManager("System.Data.Entity.Design", typeof(System.Data.Entity.Design.MetadataItemCollectionFactory).Assembly);
+	}
+	
+    return _resourceManager2.GetString(resourceName, null);
+}
+System.Resources.ResourceManager _resourceManager2;
+
+void WriteHeader(EntityFrameworkTemplateFileManager fileManager)
+{
+    fileManager.StartHeader();
+#>
+//------------------------------------------------------------------------------
+// <auto-generated>
+//    This code was generated from a template.
+//
+//    Manual changes to this file may cause unexpected behavior in your application.
+//    Manual changes to this file will be overwritten if the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+<#+
+    fileManager.EndBlock();
+}
+
+void BeginNamespace(string namespaceName, CodeGenerationTools code)
+{
+    CodeRegion region = new CodeRegion(this);
+    if (!String.IsNullOrEmpty(namespaceName))
+    {
+#>
+namespace <#=code.EscapeNamespace(namespaceName)#>
+{
+<#+
+        PushIndent(CodeRegion.GetIndent(1));
+    }
+}
+
+
+void EndNamespace(string namespaceName)
+{
+    if (!String.IsNullOrEmpty(namespaceName))
+    {
+        PopIndent();
+#>
+}
+<#+
+    }
+}
+string ToTable(EntitySet entitySet)
+{
+	var toTable = entitySet.Name;
+	string schema = entitySet.GetSchemaName();
+	if(!string.IsNullOrWhiteSpace(schema) && schema != "dbo")	
+		toTable += "\", \"" + schema;
+	return toTable;
+}
+
+bool VerifyTypesAreCaseInsensitiveUnique(EdmItemCollection itemCollection)
+{
+    var alreadySeen = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
+    foreach(var type in itemCollection.GetItems<StructuralType>())
+    {
+        if (!(type is EntityType || type is ComplexType))
+        {
+            continue;
+        }
+
+        if (alreadySeen.ContainsKey(type.FullName))
+        {
+            Error(String.Format(CultureInfo.CurrentCulture, "This template does not support types that differ only by case, the types {0} are not supported", type.FullName));
+            return false;
+        }
+        else
+        {
+            alreadySeen.Add(type.FullName, true);
+        }
+    }
+
+    return true;
+}
+
+string GetGenerationOption(EdmProperty property, EntityType entity)
+{
+	string result = "";
+	bool isPk = entity.KeyMembers.Contains(property);
+	MetadataProperty storeGeneratedPatternProperty = null;
+	string storeGeneratedPatternPropertyValue = "None";
+	
+	if(property.MetadataProperties.TryGetValue(MetadataConsts.EDM_ANNOTATION_09_02 + ":StoreGeneratedPattern", false, out storeGeneratedPatternProperty))	
+		storeGeneratedPatternPropertyValue = storeGeneratedPatternProperty.Value.ToString();		
+	
+	PrimitiveType edmType = (PrimitiveType) property.TypeUsage.EdmType; 
+	if (storeGeneratedPatternPropertyValue == "Computed")
+	{
+	    result = ".HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed)";
+	}
+	else if ((edmType.ClrEquivalentType == typeof(int)) || (edmType.ClrEquivalentType == typeof(short)) || (edmType.ClrEquivalentType == typeof(long)))
+	{
+	    if (isPk && (storeGeneratedPatternPropertyValue != "Identity"))
+	        result = ".HasDatabaseGeneratedOption(DatabaseGeneratedOption.None)";
+	    else if ((!isPk || (entity.KeyMembers.Count > 1)) && (storeGeneratedPatternPropertyValue == "Identity"))
+	        result = ".HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)";
+	}	
+	return result;    
+}
+
+MetadataLoadResult LoadMetadata(string inputFile)
+{       
+	var loader = new MetadataLoader(this);
+	bool loaded = false;
+	EdmItemCollection edmItemCollection = loader.CreateEdmItemCollection(inputFile);      
+	StoreItemCollection storeItemCollection = null;
+	if (loader.TryCreateStoreItemCollection(inputFile, out storeItemCollection))
+	{
+		StorageMappingItemCollection storageMappingItemCollection;
+		if (loader.TryCreateStorageMappingItemCollection(inputFile, edmItemCollection, storeItemCollection, out storageMappingItemCollection))
+			loaded = true;
+	}
+
+	if(loaded == false)
+		throw new Exception("Cannot load a metadata from the file " + inputFile);
+
+	var mappingMetadata = LoadMappingMetadata(inputFile);
+	var mappingNode		= mappingMetadata.Item1;
+	var nsmgr			= mappingMetadata.Item2;
+
+	var allEntitySets = storeItemCollection.GetAllEntitySets();		
+
+	return new MetadataLoadResult
+	       	{
+	       		EdmItems = edmItemCollection,
+	       		PropertyToColumnMapping = BuildEntityMappings(mappingNode, nsmgr, edmItemCollection.GetItems<EntityType>(), edmItemCollection.GetAllEntitySets(), allEntitySets),
+	       		ManyToManyMappings = BuildManyToManyMappings(mappingNode, nsmgr, edmItemCollection.GetAllAssociationSets(), allEntitySets),
+				TphMappings=BuildTPHMappings(mappingNode, nsmgr, edmItemCollection.GetItems<EntityType>(), edmItemCollection.GetAllEntitySets(), allEntitySets)
+	       	};
+}
+
+private Tuple<XmlNode, XmlNamespaceManager> LoadMappingMetadata(string inputFile)
+{
+	var xmlDoc = new XmlDocument();
+     xmlDoc.Load(Host.ResolvePath(inputFile));
+
+	 var schemaConstantsList = new SchemaConsts[]
+					{						
+						MetadataConsts.V2_SCHEMA_CONSTANTS,
+						MetadataConsts.V1_SCHEMA_CONSTANTS
+					};
+	foreach (var schemaConstants in schemaConstantsList)
+	{
+		var nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
+		nsmgr.AddNamespace("ef", schemaConstants.MslNamespace);
+		nsmgr.AddNamespace("edmx", schemaConstants.EdmxNamespace);
+		var mappingNode = xmlDoc.DocumentElement.SelectSingleNode("./*/edmx:Mappings", nsmgr);
+
+		if(mappingNode != null)
+			return Tuple.Create(mappingNode, nsmgr);
+	}     
+
+	throw new Exception(GetResourceString("Template_UnsupportedSchema"));
+}
+
+private Dictionary<EntityType, Dictionary<EntityType, Dictionary<EdmProperty, string>>> BuildTPHMappings(XmlNode mappingNode, XmlNamespaceManager nsmgr, IEnumerable<EntityType> entityTypes, IEnumerable<EntitySet> entitySets, IEnumerable<EntitySet> tableSets)
+{
+	var dictionary = new Dictionary<EntityType, Dictionary<EntityType, Dictionary<EdmProperty, string>>>();	
+	foreach (EntitySet set in entitySets)
+	{
+		XmlNodeList nodes = mappingNode.SelectNodes(string.Format(".//ef:EntitySetMapping[@Name=\"{0}\"]/ef:EntityTypeMapping/ef:MappingFragment", set.Name), nsmgr);
+		foreach(XmlNode node in nodes)
+		{
+			string typeName=node.ParentNode.Attributes["TypeName"].Value;
+			if(typeName.StartsWith("IsTypeOf("))
+				typeName=typeName.Substring("IsTypeOf(".Length, typeName.Length-"IsTypeOf()".Length);
+			EntityType type=entityTypes.Single(z=>z.FullName==typeName);
+			string tableName = node.Attributes["StoreEntitySet"].Value;
+			EntitySet set2 = tableSets.Single(entitySet => entitySet.Name == tableName);
+			var entityMap = new Dictionary<EdmProperty, string>();
+			
+			XmlNodeList propertyNodes = node.SelectNodes("./ef:Condition", nsmgr);
+			if(propertyNodes.Count==0) continue;
+			foreach(XmlNode propertyNode in propertyNodes)
+			{
+				string str = propertyNode.Attributes["ColumnName"].Value;
+				EdmProperty property2 = set2.ElementType.Properties[str];
+				string val=propertyNode.Attributes["Value"].Value;
+				entityMap.Add(property2, val);
+			}
+			EntityType baseType=(EntityType)(type.BaseType??type);
+			if(!dictionary.Keys.Contains(baseType))
+			{
+			var entityMappings=new Dictionary<EntityType, Dictionary<EdmProperty, string>>();
+			//entityMappings.Add(type,entityMap);
+			dictionary.Add(baseType, entityMappings);
+			}
+			dictionary[baseType].Add(type,entityMap);
+		}
+	}
+	return dictionary;
+}		
+
+private Dictionary<EntityType, Tuple<EntitySet, Dictionary<EdmProperty, EdmProperty>>> BuildEntityMappings(XmlNode mappingNode, XmlNamespaceManager nsmgr, IEnumerable<EntityType> entityTypes, IEnumerable<EntitySet> entitySets, IEnumerable<EntitySet> tableSets)
+{
+	var dictionary = new Dictionary<EntityType, Tuple<EntitySet, Dictionary<EdmProperty, EdmProperty>>>();
+
+	foreach (EntitySet set in entitySets)
+	{
+		XmlNodeList nodes = mappingNode.SelectNodes(string.Format(".//ef:EntitySetMapping[@Name=\"{0}\"]/ef:EntityTypeMapping/ef:MappingFragment", set.Name), nsmgr);
+		foreach(XmlNode node in nodes)
+		{
+			string typeName=node.ParentNode.Attributes["TypeName"].Value;
+			if(typeName.StartsWith("IsTypeOf("))
+				typeName=typeName.Substring("IsTypeOf(".Length, typeName.Length-"IsTypeOf()".Length);
+			EntityType type=entityTypes.Single(z=>z.FullName==typeName);
+			string tableName = node.Attributes["StoreEntitySet"].Value;
+			EntitySet set2 = tableSets.Single(entitySet => entitySet.Name == tableName);
+			var entityMap = new Dictionary<EdmProperty, EdmProperty>();
+			foreach (EdmProperty property in type.Properties)
+			{
+				XmlNode propertyNode = node.SelectSingleNode(string.Format("./ef:ScalarProperty[@Name=\"{0}\"]", property.Name), nsmgr);
+				if(propertyNode == null) continue;
+				string str = propertyNode.Attributes["ColumnName"].Value;
+				EdmProperty property2 = set2.ElementType.Properties[str];
+				entityMap.Add(property, property2);
+			}
+			dictionary.Add(type, Tuple.Create(set2, entityMap));
+		}
+	}
+	return dictionary;
+}
+
+Dictionary<AssociationType, Tuple<EntitySet, Dictionary<RelationshipEndMember, Dictionary<EdmMember, string>>>> BuildManyToManyMappings(XmlNode mappingNode, XmlNamespaceManager nsmgr, IEnumerable<AssociationSet> associationSets, IEnumerable<EntitySet> tableSets)
+{
+	var dictionary = new Dictionary<AssociationType, Tuple<EntitySet, Dictionary<RelationshipEndMember, Dictionary<EdmMember, string>>>>();
+	foreach (AssociationSet associationSet in associationSets.Where(set => set.ElementType.IsManyToMany()))
+	{
+		
+		XmlNode node = mappingNode.SelectSingleNode(string.Format("//ef:AssociationSetMapping[@Name=\"{0}\"]", associationSet.Name), nsmgr);
+		string tableName = node.Attributes["StoreEntitySet"].Value;
+		EntitySet entitySet = tableSets.Single(s => s.Name == tableName);
+		
+		var relationEndMap = new Dictionary<RelationshipEndMember, Dictionary<EdmMember, string>>();
+		foreach (AssociationSetEnd end in associationSet.AssociationSetEnds)
+		{
+			var map = new Dictionary<EdmMember, string>();
+			foreach (XmlNode endProperty in node.SelectSingleNode(string.Format("./ef:EndProperty[@Name=\"{0}\"]", end.Name), nsmgr).ChildNodes)
+			{
+				string str = endProperty.Attributes["Name"].Value;
+				EdmProperty key = end.EntitySet.ElementType.Properties[str];
+				string str2 = endProperty.Attributes["ColumnName"].Value;
+				map.Add(key, str2);
+			}
+			relationEndMap.Add(end.CorrespondingAssociationEndMember, map);
+		}
+		dictionary.Add(associationSet.ElementType, Tuple.Create(entitySet, relationEndMap));
+	}
+	return dictionary;
+}
+
+public class MetadataLoadResult
+{
+	public EdmItemCollection EdmItems { get; set; }
+	public Dictionary<EntityType, Tuple<EntitySet, Dictionary<EdmProperty, EdmProperty>>> PropertyToColumnMapping { get; set; }
+	public Dictionary<AssociationType, Tuple<EntitySet, Dictionary<RelationshipEndMember, Dictionary<EdmMember, string>>>> ManyToManyMappings { get; set; }
+	public Dictionary<EntityType, Dictionary<EntityType, Dictionary<EdmProperty, string>>> TphMappings { get; set; }
+}
+
+/// <summary>
+/// Responsible for encapsulating the constants defined in Metadata
+/// </summary>
+public static class MetadataConsts
+{
+    public const string CSDL_EXTENSION = ".csdl";
+
+    public const string CSDL_EDMX_SECTION_NAME = "ConceptualModels";
+    public const string CSDL_ROOT_ELEMENT_NAME = "Schema";
+    public const string EDM_ANNOTATION_09_02 = "http://schemas.microsoft.com/ado/2009/02/edm/annotation";
+
+    public const string SSDL_EXTENSION = ".ssdl";
+
+    public const string SSDL_EDMX_SECTION_NAME = "StorageModels";
+    public const string SSDL_ROOT_ELEMENT_NAME = "Schema";
+
+    public const string MSL_EXTENSION = ".msl";
+
+    public const string MSL_EDMX_SECTION_NAME = "Mappings";
+    public const string MSL_ROOT_ELEMENT_NAME = "Mapping";
+
+    public const string TT_TEMPLATE_NAME = "TemplateName";
+    public const string TT_TEMPLATE_VERSION = "TemplateVersion";
+    public const string TT_MINIMUM_ENTITY_FRAMEWORK_VERSION = "MinimumEntityFrameworkVersion";
+
+    public const string DEFAULT_TEMPLATE_VERSION = "4.0";
+
+    public static readonly SchemaConsts V1_SCHEMA_CONSTANTS = new SchemaConsts(
+        "http://schemas.microsoft.com/ado/2007/06/edmx",
+        "http://schemas.microsoft.com/ado/2006/04/edm",
+        "http://schemas.microsoft.com/ado/2006/04/edm/ssdl",
+        "urn:schemas-microsoft-com:windows:storage:mapping:CS",
+        new Version("3.5"));
+
+    public static readonly SchemaConsts V2_SCHEMA_CONSTANTS = new SchemaConsts(
+        "http://schemas.microsoft.com/ado/2008/10/edmx",
+        "http://schemas.microsoft.com/ado/2008/09/edm",
+        "http://schemas.microsoft.com/ado/2009/02/edm/ssdl",
+        "http://schemas.microsoft.com/ado/2008/09/mapping/cs",
+        new Version("4.0"));
+
+    public static readonly SchemaConsts V3_SCHEMA_CONSTANTS = new SchemaConsts(
+        "http://schemas.microsoft.com/ado/2009/11/edmx",
+        "http://schemas.microsoft.com/ado/2009/11/edm",
+        "http://schemas.microsoft.com/ado/2009/11/edm/ssdl",
+        "http://schemas.microsoft.com/ado/2009/11/mapping/cs",
+        new Version("4.5"));
+}
+
+public struct SchemaConsts
+{
+    public SchemaConsts(string edmxNamespace, string csdlNamespace, string ssdlNamespace, string mslNamespace, Version minimumTemplateVersion) : this()
+    {
+        EdmxNamespace = edmxNamespace;
+        CsdlNamespace = csdlNamespace;
+        SsdlNamespace = ssdlNamespace;
+        MslNamespace = mslNamespace;
+        MinimumTemplateVersion = minimumTemplateVersion;
+    }
+
+   public string EdmxNamespace { get; private set; }
+    public string CsdlNamespace { get; private set; }
+    public string SsdlNamespace { get; private set; }
+    public string MslNamespace { get; private set; }
+    public Version MinimumTemplateVersion { get; private set; }
+}
+#>

+ 58 - 0
EMIS.Entities.Log/VW_Sys_User.cs

@@ -0,0 +1,58 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//    This code was generated from a template.
+//
+//    Manual changes to this file may cause unexpected behavior in your application.
+//    Manual changes to this file will be overwritten if the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace EMIS.Entities.Log
+{
+    #pragma warning disable 1573
+    using System;
+    using System.Collections.Generic;
+    
+    /// <summary>
+    /// VW_Sys_User
+    /// </summary>
+    public partial class VW_Sys_User
+    {
+    	/// <summary>
+        /// UserID
+        /// </summary>
+        public System.Guid UserID { get; set; }
+    	/// <summary>
+        /// LoginID
+        /// </summary>
+        public string LoginID { get; set; }
+    	/// <summary>
+        /// Password
+        /// </summary>
+        public string Password { get; set; }
+    	/// <summary>
+        /// Name
+        /// </summary>
+        public string Name { get; set; }
+    	/// <summary>
+        /// RecordStatus
+        /// </summary>
+        public Nullable<int> RecordStatus { get; set; }
+    	/// <summary>
+        /// CreateUserID
+        /// </summary>
+        public Nullable<System.Guid> CreateUserID { get; set; }
+    	/// <summary>
+        /// CreateTime
+        /// </summary>
+        public Nullable<System.DateTime> CreateTime { get; set; }
+    	/// <summary>
+        /// ModifyUserID
+        /// </summary>
+        public Nullable<System.Guid> ModifyUserID { get; set; }
+    	/// <summary>
+        /// ModifyTime
+        /// </summary>
+        public Nullable<System.DateTime> ModifyTime { get; set; }
+    }
+}

+ 40 - 0
EMIS.Entities.Log/VW_Sys_User_Mapping.cs

@@ -0,0 +1,40 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//    This code was generated from a template.
+//
+//    Manual changes to this file may cause unexpected behavior in your application.
+//    Manual changes to this file will be overwritten if the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace EMIS.Entities.Log
+{
+    #pragma warning disable 1573
+    using System;
+    using System.Collections.Generic;
+    using System.ComponentModel.DataAnnotations;
+    using System.Data.Common;
+    using System.Data.Entity;
+    using System.Data.Entity.ModelConfiguration;
+    using System.Data.Entity.Infrastructure;
+    using System.ComponentModel.DataAnnotations.Schema;
+    
+    internal partial class VW_Sys_User_Mapping : EntityTypeConfiguration<VW_Sys_User>
+    {
+        public VW_Sys_User_Mapping()
+        {					
+    		this.HasKey(t => t.UserID);		
+    		this.ToTable("VW_Sys_User");
+    		this.Property(t => t.UserID).HasColumnName("UserID");
+    		this.Property(t => t.LoginID).HasColumnName("LoginID").IsUnicode(false).HasMaxLength(50);
+    		this.Property(t => t.Password).HasColumnName("Password").IsUnicode(false).HasMaxLength(50);
+    		this.Property(t => t.Name).HasColumnName("Name").HasMaxLength(50);
+    		this.Property(t => t.RecordStatus).HasColumnName("RecordStatus");
+    		this.Property(t => t.CreateUserID).HasColumnName("CreateUserID");
+    		this.Property(t => t.CreateTime).HasColumnName("CreateTime");
+    		this.Property(t => t.ModifyUserID).HasColumnName("ModifyUserID");
+    		this.Property(t => t.ModifyTime).HasColumnName("ModifyTime");
+    	}
+    }
+}
+

+ 5 - 0
EMIS.Entities.Log/packages.config

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="EntityFramework" version="6.1.3" targetFramework="net40" />
+  <package id="EntityFramework.Extended" version="6.1.0.168" targetFramework="net40" />
+</packages>

+ 12 - 0
EMIS.Utility/Log/BatchModifyDbLog.cs

@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace EMIS.Utility.Log
+{
+    public class BatchModifyDbLog
+    {
+
+    }
+}

+ 315 - 0
EMIS.Utility/Log/DbLog.cs

@@ -0,0 +1,315 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Data.Entity.Infrastructure;
+using EMIS.Utility.FormValidate;
+using Bowin.Common.Data;
+using System.Web;
+using System.Data;
+using System.Linq.Expressions;
+
+namespace EMIS.Utility.Log
+{
+    public class DbLog
+    {
+        public static List<Log_Operate> GetBatchUpdateLog<T>(IList<T> entities, System.Data.Entity.DbContext ctx) where T : class
+        {
+            var result = new List<Log_Operate>();
+            var principal = CustomPrincipal.Current;
+            var operateUserID = (principal != null) ? (Guid?)principal.UserID : null;
+
+            var tableKey = EMIS.Entities.TableKeyDictionary.GetKeyName<T>();
+            ParameterExpression keyParamter = Expression.Parameter(typeof(DbEntityEntry<T>), "w");
+            MemberExpression keyEntryExpression = Expression.Property(keyParamter, "Entity");
+            MemberExpression keyExpression = Expression.Property(keyEntryExpression, tableKey);
+            var entryList = ctx.ChangeTracker.Entries<T>().ToList();
+            var originalValues = entities.Select(x => new {
+                OriginalValues = entryList.FirstOrDefault(
+                    Expression.Lambda<Func<DbEntityEntry<T>, bool>>(
+                        Expression.Equal(keyExpression, Expression.Constant((Guid)typeof(T).GetProperty(tableKey).GetValue(x, null)))
+                    , keyParamter).Compile()).OriginalValues,
+                CurrentValues = x
+            }).ToList();
+
+            foreach (var updateChange in originalValues)
+            {
+                var log = new Log_Operate
+                {
+                    OperateID = Guid.NewGuid(),
+                    UserID = operateUserID,
+                    IP = ApplicationClientHelper.GetIP(),
+                    TableName = updateChange.CurrentValues.GetType().Name,
+                    SourceUrl = (HttpContext.Current == null) ? null : HttpContext.Current.Request.UrlReferrer.OriginalString,
+                    OperateTime = DateTime.Now
+                };
+                log.Operate = "修改";
+                log.Detail = "修改前内容(" + GatherValues(updateChange.OriginalValues) + "),";
+                log.Detail += "修改后内容(" + GatherValues(updateChange.CurrentValues) + ")";
+
+                result.Add(log);
+            }
+
+            return result;
+        }
+
+        public static List<Log_Operate> GetBulkInsertLog<T>(IList<T> entities)
+        {
+            var table = entities.ToTable();
+            return GetBulkInsertLog(table, typeof(T).Name);
+        }
+        public static List<Log_Operate> GetBulkInsertLog(DataTable table, string tableName)
+        {
+            var result = new List<Log_Operate>();
+            var principal = CustomPrincipal.Current;
+            var operateUserID = (principal != null) ? (Guid?)principal.UserID : null;
+            var myIP = ApplicationClientHelper.GetIP();
+
+            foreach (DataRow row in table.Rows)
+            {
+                var value = "详细内容(";
+                for (int i = 0; i < table.Columns.Count; i++)
+                {
+                    string columnName = table.Columns[i].ColumnName;
+                    value += columnName + ":";
+                    value += row[columnName].ToString() + "|";
+                }
+                if (value.EndsWith("|"))
+                {
+                    value = value.TrimEnd('|');
+                }
+                value += ")";
+
+                Log_Operate operate = new Log_Operate()
+                {
+                    OperateID = Guid.NewGuid(),
+                    UserID = operateUserID,
+                    IP = myIP,
+                    TableName = tableName,
+                    SourceUrl = (HttpContext.Current == null) ? null : HttpContext.Current.Request.UrlReferrer.OriginalString,
+                    OperateTime = DateTime.Now,
+                    Operate = "新增",
+                    Detail = value
+                };
+
+                result.Add(operate);
+            }
+
+            return result;
+        }
+
+        public static List<Log_Operate> GetDeleteLog<T>(IList<T> entities)
+        {
+            var table = entities.ToTable();
+            return GetDeleteLog(table, typeof(T).Name);
+        }
+        public static List<Log_Operate> GetDeleteLog(DataTable table, string tableName)
+        {
+            var result = new List<Log_Operate>();
+            var principal = CustomPrincipal.Current;
+            var operateUserID = (principal != null) ? (Guid?)principal.UserID : null;
+            var myIP = ApplicationClientHelper.GetIP();
+
+            foreach (DataRow row in table.Rows)
+            {
+                var value = "删除内容(";
+                for (int i = 0; i < table.Columns.Count; i++)
+                {
+                    string columnName = table.Columns[i].ColumnName;
+                    value += columnName + ":";
+                    value += row[columnName].ToString() + "|";
+                }
+                if (value.EndsWith("|"))
+                {
+                    value = value.TrimEnd('|');
+                }
+                value += ")";
+
+                Log_Operate operate = new Log_Operate()
+                {
+                    OperateID = Guid.NewGuid(),
+                    UserID = operateUserID,
+                    IP = myIP,
+                    TableName = tableName,
+                    SourceUrl = (HttpContext.Current == null) ? null : HttpContext.Current.Request.UrlReferrer.OriginalString,
+                    OperateTime = DateTime.Now,
+                    Operate = "删除",
+                    Detail = value
+                };
+
+                result.Add(operate);
+            }
+
+            return result;
+        }
+
+        public static List<Log_Operate> GetLog(DbChangeTracker changeTracker)
+        {
+            var result = new List<Log_Operate>();
+            var entryList = changeTracker.Entries().ToList();
+            var principal = CustomPrincipal.Current;
+
+            entryList.ForEach(x => AddLog(x, result, principal));
+
+            return result;
+        }
+
+        public static List<Log_Operate> GetRelationshipLog(System.Data.Entity.DbContext ctx)
+        {
+            var result = new List<Log_Operate>();
+            var principal = CustomPrincipal.Current;
+            var operateUserID = (principal != null) ? (Guid?)principal.UserID : null;
+            var objectContext = ((IObjectContextAdapter)ctx).ObjectContext;
+            var deleteChanges = objectContext.ObjectStateManager.GetObjectStateEntries(System.Data.Entity.EntityState.Deleted);
+            var addChanges = objectContext.ObjectStateManager.GetObjectStateEntries(System.Data.Entity.EntityState.Added);
+            var myIP = ApplicationClientHelper.GetIP();
+
+            foreach(var deleteChange in deleteChanges)
+            {
+                if (deleteChange.IsRelationship)
+                {
+                    var log = new Log_Operate
+                    {
+                        OperateID = Guid.NewGuid(),
+                        UserID = operateUserID,
+                        IP = myIP,
+                        TableName = deleteChange.EntitySet.Name,
+                        SourceUrl = (HttpContext.Current == null) ? null : HttpContext.Current.Request.UrlReferrer.OriginalString,
+                        OperateTime = DateTime.Now,
+                        Operate = "删除",
+                        Detail = "删除内容(" + GatherValues(deleteChange.OriginalValues) + ")"
+                    };
+                    result.Add(log);
+                }
+            }
+            foreach (var addChange in addChanges)
+            {
+                if (addChange.IsRelationship)
+                {
+                    var log = new Log_Operate
+                    {
+                        OperateID = Guid.NewGuid(),
+                        UserID = operateUserID,
+                        IP = myIP,
+                        TableName = addChange.EntitySet.Name,
+                        SourceUrl = (HttpContext.Current == null) ? null : HttpContext.Current.Request.UrlReferrer.OriginalString,
+                        OperateTime = DateTime.Now,
+                        Operate = "新增",
+                        Detail = "详细内容(" + GatherRelationValues(addChange.CurrentValues, objectContext) + ")"
+                    };
+                    result.Add(log);
+                }
+            }
+
+            return result;
+        }
+
+        private static void AddLog(DbEntityEntry entry, IList<Log_Operate> logList, CustomPrincipal principal)
+        {
+            var operateUserID = (principal != null) ? (Guid?)principal.UserID : null;
+            var log = new Log_Operate { 
+                    OperateID = Guid.NewGuid(),
+                    UserID = operateUserID,
+                    IP = ApplicationClientHelper.GetIP(),
+                    TableName = entry.Entity.GetType().Name,
+                    SourceUrl = (HttpContext.Current == null) ? null : HttpContext.Current.Request.UrlReferrer.OriginalString,
+                    OperateTime = DateTime.Now
+                };
+            switch (entry.State)
+            {
+                case System.Data.Entity.EntityState.Added:
+                    log.Operate = "新增";
+                    log.Detail = "详细内容(" + GatherValues(entry.CurrentValues) + ")";
+                    break;
+                case System.Data.Entity.EntityState.Modified:
+                    log.Operate = "修改";
+                    log.Detail = "修改前内容(" + GatherValues(entry.OriginalValues) + "),";
+                    log.Detail += "修改后内容(" + GatherValues(entry.CurrentValues) + ")";
+                    break;
+                case System.Data.Entity.EntityState.Deleted:
+                    log.Operate = "删除";
+                    log.Detail = "删除内容(" + GatherValues(entry.OriginalValues) + ")";
+                    break;
+                default:
+                    return;
+            }
+
+            logList.Add(log);
+        }
+
+        private static string GatherRelationValues(System.Data.Common.DbDataRecord values, 
+            System.Data.Entity.Core.Objects.ObjectContext context)
+        {
+            var result = "";
+            for (int i = 0; i < values.FieldCount; i ++ )
+            {
+                var entry = (System.Data.Entity.Core.EntityKey)values.GetValue(i);
+                result += entry.EntitySetName + ":";
+                var entity = context.GetObjectByKey(entry);
+                var entityType = entity.GetType();
+                var propertyName = entry.GetEntitySet(context.MetadataWorkspace).ElementType.KeyMembers[0].Name;
+                var property = entityType.GetProperty(propertyName);
+                result += property.GetValue(entity, null) + "|";
+                //foreach (var property in entityType.GetProperties())
+                //{
+                //    result += property.Name + ":" + property.GetValue(entity, null) + "|";
+                //}
+            }
+            if (result.EndsWith("|"))
+            {
+                result = result.TrimEnd('|');
+            }
+
+            return result;
+        }
+
+        private static string GatherValues(System.Data.Common.DbDataRecord values)
+        {
+            var result = "";
+            for (int i = 0; i < values.FieldCount; i ++ )
+            {
+                var entry = (System.Data.Entity.Core.EntityKey)values.GetValue(i);
+                result += entry.EntitySetName + ":" + entry.EntityKeyValues[0].Value.ToString() + "|";
+            }
+            if (result.EndsWith("|"))
+            {
+                result = result.TrimEnd('|');
+            }
+
+            return result;
+        }
+
+        private static string GatherValues(DbPropertyValues values)
+        {
+            var result = "";
+            foreach (var propertyName in values.PropertyNames)
+            {
+                result += propertyName + ":" + values[propertyName] + "|";
+            }
+            if (result.EndsWith("|"))
+            {
+                result = result.TrimEnd('|');
+            }
+
+            return result;
+        }
+
+        private static string GatherValues<T>(T entity)
+        {
+            var result = "";
+            var properties = typeof(T).GetProperties();
+            foreach (var property in properties)
+            {
+                if (property.PropertyType.IsPrimitive || property.PropertyType.IsValueType || property.PropertyType.Name.StartsWith("String"))
+                {
+                    result += property.Name + ":" + (property.GetValue(entity, null) ?? "").ToString() + "|";
+                }
+            }
+            if (result.EndsWith("|"))
+            {
+                result = result.TrimEnd('|');
+            }
+
+            return result;
+        }
+    }
+}

+ 52 - 0
EMIS.ViewModel/Log/OperateLogView.cs

@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace EMIS.ViewModel.Log
+{
+    public class OperateLogView
+    {
+        /// <summary>
+        /// OperateID
+        /// </summary>
+        public System.Guid OperateID { get; set; }
+        /// <summary>
+        /// UserID
+        /// </summary>
+        public Nullable<System.Guid> UserID { get; set; }
+
+        public string LoginID { get; set; }
+        public string UserName { get; set; }
+        /// <summary>
+        /// IP
+        /// </summary>
+        public string IP { get; set; }
+        /// <summary>
+        /// TableName
+        /// </summary>
+        public string TableName { get; set; }
+        /// <summary>
+        /// SourceUrl
+        /// </summary>
+        public string SourceUrl { get; set; }
+        /// <summary>
+        /// Operate
+        /// </summary>
+        public string Operate { get; set; }
+        /// <summary>
+        /// Detail
+        /// </summary>
+        public string Detail { get; set; }
+        /// <summary>
+        /// IsSuccess
+        /// </summary>
+        public Nullable<bool> IsSuccess { get; set; }
+
+        public string IsSuccessDesc { get; set; }
+        /// <summary>
+        /// OperateTime
+        /// </summary>
+        public Nullable<System.DateTime> OperateTime { get; set; }
+    }
+}

+ 46 - 0
Framework/Bowin.Common/Log/LogHelper.cs

@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NLog;
+
+namespace Bowin.Common.Log
+{
+    public enum LogType
+    {
+        CommmLog, //通用日志
+        ServiceLog
+    }
+
+    public class LogHelper
+    {
+        /// <summary>
+        /// 直接使用这个的话,类型就是Info(信息)
+        /// </summary>
+        /// <param name="logType"></param>
+        /// <param name="message"></param>
+        public static void WriteLog(LogType logType, string message)
+        {
+            //不要重载
+            LogManager.GetLogger(logType.ToString()).Log(LogLevel.Info, message.Replace("'", "''"));
+        }
+
+        public static void WriteErrorLog(LogType logType, string message)
+        {
+            //不要重载
+            LogManager.GetLogger(logType.ToString()).Log(LogLevel.Error, message.Replace("'", "''"));
+        }
+
+        public static void WriteLog(LogType logType, string message, LogLevel logLevel)
+        {
+            //不要重载
+            LogManager.GetLogger(logType.ToString()).Log(logLevel, message.Replace("'", "''"));
+        }
+
+        public static void WriteDebugLog(LogType logType, string message)
+        {
+            //不要重载
+            LogManager.GetLogger(logType.ToString()).Log(LogLevel.Debug, message.Replace("'", "''"));
+        }
+    }
+}

BIN
Lib/Bowin.Common.pdb


+ 42 - 0
ServiceLogic/EMIS.CommonLogic/Log/OperateLogServices.cs

@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using EMIS.ViewModel.Log;
+using Bowin.Common.Linq.Entity;
+using EMIS.ViewModel;
+using EMIS.DataLogic.Log;
+using System.Linq.Expressions;
+using EMIS.Entities.Log;
+
+namespace EMIS.CommonLogic.Log
+{
+    public class OperateLogServices : BaseServices, IOperateLogServices
+    {
+        public OperateLogDAL OperateLogDAL { get; set; }
+
+        public IGridResultSet<OperateLogView> GetOperateLogViewList(ConfiguretView searchCondition, DateTime startTime, DateTime endTime
+            , int pageIndex, int pageSize)
+        {
+            var q = OperateLogDAL.GetOperateLogView(x => (x.OperateTime >= startTime && x.OperateTime <= endTime), x => true);
+            if (!string.IsNullOrEmpty(searchCondition.ConditionValue) && !string.IsNullOrEmpty(searchCondition.Attribute))
+                q = q.DynamicWhere(searchCondition.Attribute, searchCondition.Condition, searchCondition.ConditionValue);
+
+            return q.OrderByDescending(x => x.OperateTime).ToGridResultSet<OperateLogView>(pageIndex, pageSize);
+        }
+
+        public IList<OperateLogView> GetOperateLogViewList(ConfiguretView searchCondition, DateTime startTime, DateTime endTime)
+        {
+            var q = OperateLogDAL.GetOperateLogView(x => (x.OperateTime >= startTime && x.OperateTime <= endTime), x => true);
+            if (!string.IsNullOrEmpty(searchCondition.ConditionValue) && !string.IsNullOrEmpty(searchCondition.Attribute))
+                q = q.DynamicWhere(searchCondition.Attribute, searchCondition.Condition, searchCondition.ConditionValue);
+
+            return q.OrderByDescending(x => x.OperateTime).ToList();
+        }
+
+        public void Delete(IList<Guid?> logIDList)
+        {
+            this.LogUnitOfWork.RemoveLogs(logIDList);
+        }
+    }
+}

+ 34 - 0
ServiceLogic/EMIS.ICommonLogic/Log/IOperateLogServices.cs

@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Bowin.Common.Linq.Entity;
+using EMIS.ViewModel.Log;
+using EMIS.ViewModel;
+
+namespace EMIS.CommonLogic.Log
+{
+    public interface IOperateLogServices
+    {
+        /// <summary>
+        /// 获取日志列表
+        /// </summary>
+        /// <param name="searchCondition">动态查询条件</param>
+        /// <param name="startTime">开始时间(必填)</param>
+        /// <param name="endTime">结束时间(必填)</param>
+        /// <param name="pageIndex">页码</param>
+        /// <param name="pageSize">每页行数</param>
+        /// <returns>数据库分页后的单页结果,以及总记录数</returns>
+        IGridResultSet<OperateLogView> GetOperateLogViewList(ConfiguretView searchCondition, DateTime startTime, DateTime endTime, int pageIndex, int pageSize);
+        /// <summary>
+        /// 获取日志列表
+        /// </summary>
+        /// <param name="searchCondition">动态查询条件</param>
+        /// <param name="startTime">开始时间(必填)</param>
+        /// <param name="endTime">结束时间(必填)</param>
+        /// <returns>获取全部结果</returns>
+        IList<OperateLogView> GetOperateLogViewList(ConfiguretView searchCondition, DateTime startTime, DateTime endTime);
+
+        void Delete(IList<Guid?> logIDList);
+    }
+}

Файловите разлики са ограничени, защото са твърде много
+ 1704 - 0
数据字典/教务系统松山版.pdb


Файловите разлики са ограничени, защото са твърде много
+ 89651 - 0
数据字典/教务系统通用版.pdb


Файловите разлики са ограничени, защото са твърде много
+ 1910 - 0
数据字典/教务系统通用版日志.pdb