public static void MyClassInitialize(TestContext testContext) { RepositoryPoco repository = new RepositoryPoco { DcFullClassName = typeof (TestDataContext).FullName, RepositoryName = "Test" }; EntityPoco entity; PropertyPoco property; #region Родитель repository.Entities.Add(entity = new EntityPoco { RpName = EntityParentName, DcFullName = typeof (Parent).FullName, }); entity.Properties.Add(new PropertyPoco { DisplayName = "Parent ID", DcName = "ParentID", RpName = "ParentID", IsPK = true, NotNull = true, Type = "System.Guid" }); entity.Properties.Add(property = new PropertyPoco { DisplayName = "Целое число", DcName = "Int", RpName = "Int", CreateNullable = true, IsPK = false, NotNull = true, Type = "System.Int32", MinValue = 10, UseMinValue = true, MaxValue = 20, UseMaxValue = true }); property.CheckValues.Add(new CheckValuePoco() { Value = 13.ToString() }); property.CheckValues.Add(new CheckValuePoco() { Value = 15.ToString() }); //entity.Properties.Add(new PropertyPoco // { // DisplayName = "Целое число (nullable)", // DcName = "NullableInt", // RpName = "NullableInt", // IsPK = false, // NotNull = true, // Type = "System.Int32?", // MinValue = 10, // UseMinValue = true, // MaxValue = 20, // UseMaxValue = true // }); #endregion XmlSerializer ser = new XmlSerializer(typeof (RepositoryPoco)); string xml; using (var sw = new StringWriter()) { ser.Serialize(sw, repository); xml = sw.ToString(); } //Компили сборку CodeCompileUnit code = GeneratorCore.GenerateCode(xml); code.ReferencedAssemblies.Add(typeof (RepositoryBase<,>).Assembly.Location); code.ReferencedAssemblies.Add(typeof (IDataErrorInfo).Assembly.Location); code.ReferencedAssemblies.Add(typeof (DataContext).Assembly.Location); code.ReferencedAssemblies.Add(typeof (Expression).Assembly.Location); code.ReferencedAssemblies.Add(typeof (TestDataContext).Assembly.Location); code.ReferencedAssemblies.Add(typeof (IDbConnection).Assembly.Location); CSharpCodeProvider provider = new CSharpCodeProvider(); CompilerParameters param = new CompilerParameters() { }; using (var sw = new StringWriter()) { provider.GenerateCodeFromCompileUnit( code, sw, new CodeGeneratorOptions { BlankLinesBetweenMembers = true, BracingStyle = "C", VerbatimOrder = true }); _text = sw.ToString(); } CompilerResults results = provider.CompileAssemblyFromDom(param, code); if (results.Errors.Count == 0) _assembly = results.CompiledAssembly; }
public static void LoadFromDteProjectItem(ProjectItem item, RepositoryPoco model) { //Помечаем существующие классы и их свойста не валидными foreach (EntityPoco entity in model.Entities) { entity.NotValid = true; foreach (PropertyPoco property in entity.Properties) property.NotValid = true; } List<CodeClass> codeClasses = new List<CodeClass>(); foreach (CodeElement element in item.FileCodeModel.CodeElements) codeClasses.AddRange(GetCodeClass(element)); // Просматриваем каждый клас объявленный в файле (даже во вложенных namespace и вложенные классы) foreach (CodeClass codeClass in codeClasses) { // Выбираем классы, помеченные атрибутом TableAttribute if (codeClass.Attributes.Cast<CodeAttribute>().Any(codeAttribute => codeAttribute.FullName == "System.Data.Linq.Mapping.TableAttribute")) { EntityPoco entityPoco = model.Entities.SingleOrDefault(e => e.DcName == codeClass.Name); if (entityPoco != null) { entityPoco.DcFullName = codeClass.FullName; entityPoco.NotValid = false; } else { entityPoco = new EntityPoco { DcFullName = codeClass.FullName, DcName = codeClass.Name, RpName = codeClass.Name }; model.Entities.Add(entityPoco); } foreach (CodeElement element in codeClass.Children) { if (element.Kind == vsCMElement.vsCMElementProperty) { CodeProperty codeProperty = (CodeProperty) element; CodeAttribute attribute = codeProperty.Attributes.Cast<CodeAttribute>().SingleOrDefault(ca => ca.FullName == "System.Data.Linq.Mapping.ColumnAttribute"); if (attribute != null) { bool isNew = false; PropertyPoco propertyPoco = entityPoco.Properties.SingleOrDefault(p => p.DcName == codeProperty.Name); if (propertyPoco != null) { propertyPoco.Type = codeProperty.Type.CodeType.FullName; propertyPoco.NotValid = false; } else { propertyPoco = new PropertyPoco { DcName = codeProperty.Name, RpName = codeProperty.Name, Type = codeProperty.Type.CodeType.FullName }; entityPoco.Properties.Add(propertyPoco); isNew = true; } CodeAttributeArgument argument; argument = attribute.Children.Cast<CodeAttributeArgument>().SingleOrDefault(arg => arg.Name == "IsPrimaryKey"); if (argument != null) propertyPoco.IsPK = argument.Value == "true"; else propertyPoco.IsPK = false; argument = attribute.Children.Cast<CodeAttributeArgument>().SingleOrDefault(arg => arg.Name == "DbType"); propertyPoco.NotNull = argument != null && argument.Value.ToLower().Contains("not null"); if (argument != null) { int strLen; if (GetVarCharLength(argument.Value, out strLen)) propertyPoco.StringLength = strLen; } argument = attribute.Children.Cast<CodeAttributeArgument>().SingleOrDefault(arg => arg.Name == "IsDbGenerated"); if (argument != null) propertyPoco.IsCalculate = argument.Value == "true"; else propertyPoco.IsCalculate = false; if (isNew) { argument = attribute.Children.Cast<CodeAttributeArgument>().SingleOrDefault(arg => arg.Name == "Name"); propertyPoco.DisplayName = argument != null ? argument.Value.Replace("[", string.Empty).Replace("]", string.Empty).Replace("\"", string.Empty) : codeProperty.Name.Replace('_', ' '); } } } } } } }
/// <summary> /// Реализация для команды RemoveEntity /// </summary> /// <param name="entity">Сущность</param> private void RemoveEntityExecute(EntityPoco entity) { RepositoryModel.Entities.Remove(entity); }
private static CodeMemberMethod GetRepositoryStaticPkConditionMethod(EntityPoco entity) { CodeMemberMethod method = new CodeMemberMethod { Attributes = MemberAttributes.Static | MemberAttributes.Public, Name = RepositoryBaseStaticPkConditionMethodName, ReturnType = new CodeTypeReference("System.Linq.Expressions.Expression") }; CodeTypeReference type = new CodeTypeReference("System.Func"); type.TypeArguments.Add(entity.DcFullName); type.TypeArguments.Add("System.Boolean"); method.ReturnType.TypeArguments.Add(type); const string entityParameterName = "entity"; method.Parameters.Add(new CodeParameterDeclarationExpression(entity.RpName, entityParameterName)); if (entity.Properties.Any(p => p.IsPK)) { bool isSinglePK = false; if (entity.Properties.Count(p => p.IsPK) == 1) isSinglePK = true; CodeMethodReturnStatement result = new CodeMethodReturnStatement(); CodeSnippetExpression cs = new CodeSnippetExpression(); cs.Value += "obj =>"; foreach (PropertyPoco property in entity.Properties.Where(p => p.IsPK)) { if (isSinglePK) { cs.Value += " obj." + property.DcName + " == " + entityParameterName + "." + EntityWithPkIdPropertyName + " &&"; } else { cs.Value += " obj." + property.DcName + " == " + entityParameterName + "." + property.RpName + " &&"; } } cs.Value = cs.Value.Remove(cs.Value.Length - 2); result.Expression = cs; method.Statements.Add(result); } else { CodeThrowExceptionStatement exception = new CodeThrowExceptionStatement( new CodeObjectCreateExpression( RepositoryExceptionClassName, new CodePrimitiveExpression(string.Format("Для сущности {0} не указан первичный ключ", entity.RpName)))); method.Statements.Add(exception); } return method; }
private static CodeMemberMethod GetRepositoryStaticUpdateEntryMethod(EntityPoco entity) { const string dbEntityParameterName = "dbEntity"; const string entityParameterName = "entity"; CodeMemberMethod method = new CodeMemberMethod { Attributes = MemberAttributes.Static | MemberAttributes.Public, Name = RepositoryBaseStaticUpdateEntryMethodName }; method.Parameters.Add(new CodeParameterDeclarationExpression(entity.DcFullName, dbEntityParameterName)); method.Parameters.Add(new CodeParameterDeclarationExpression(entity.RpName, entityParameterName)); bool isSinglePK = false; if (entity.Properties.Count(p => p.IsPK) == 1) isSinglePK = true; foreach (PropertyPoco property in entity.Properties.Where(p => p.IsCalculate)) { if (property.IsPK && isSinglePK) { CodeVariableReferenceExpression dcVar = new CodeVariableReferenceExpression(dbEntityParameterName); CodePropertyReferenceExpression dcProp = new CodePropertyReferenceExpression(dcVar, property.DcName); CodeVariableReferenceExpression rpVar = new CodeVariableReferenceExpression(entityParameterName); CodePropertyReferenceExpression rpProp = new CodePropertyReferenceExpression(rpVar, EntityWithPkIdPropertyName); method.Statements.Add(new CodeAssignStatement(rpProp, dcProp)); } else { CodeVariableReferenceExpression dcVar = new CodeVariableReferenceExpression(dbEntityParameterName); CodePropertyReferenceExpression dcProp = new CodePropertyReferenceExpression(dcVar, property.DcName); CodeVariableReferenceExpression rpVar = new CodeVariableReferenceExpression(entityParameterName); CodePropertyReferenceExpression rpProp = property.IsFK ? new CodePropertyReferenceExpression(rpVar, GetIdPropertyName(property.RpName)) : new CodePropertyReferenceExpression(rpVar, property.RpName); method.Statements.Add(new CodeAssignStatement(rpProp, dcProp)); } } return method; }
private static CodeMemberMethod GetRepositoryPkConditionMethod(EntityPoco entity, string repositoryName) { CodeMemberMethod method = new CodeMemberMethod { Attributes = MemberAttributes.Override | MemberAttributes.Family, Name = RepositoryBasePkConditionMethodName, ReturnType = new CodeTypeReference("System.Linq.Expressions.Expression") }; CodeTypeReference type = new CodeTypeReference("System.Func"); type.TypeArguments.Add(entity.DcFullName); type.TypeArguments.Add("System.Boolean"); method.ReturnType.TypeArguments.Add(type); const string entityParameterName = "entity"; method.Parameters.Add(new CodeParameterDeclarationExpression(entity.RpName, entityParameterName)); method.Statements.Add( new CodeMethodReturnStatement( new CodeMethodInvokeExpression( new CodeMethodReferenceExpression( new CodeTypeReferenceExpression(repositoryName), RepositoryBaseStaticPkConditionMethodName), new CodeVariableReferenceExpression(entityParameterName)))); return method; }
private static CodeMemberMethod GetRepositoryStaticConverterMethod(EntityPoco entity) { CodeMemberMethod method = new CodeMemberMethod { Attributes = MemberAttributes.Static | MemberAttributes.Public, Name = RepositoryBaseStaticConverterMethodName, ReturnType = new CodeTypeReference("System.Linq.Expressions.Expression") }; CodeTypeReference type = new CodeTypeReference("System.Func"); type.TypeArguments.Add(entity.DcFullName); type.TypeArguments.Add(entity.RpName); method.ReturnType.TypeArguments.Add(type); CodeMethodReturnStatement result = new CodeMethodReturnStatement(); CodeSnippetExpression cs = new CodeSnippetExpression(); bool isSinglePK = false; if (entity.Properties.Count(p => p.IsPK) == 1) isSinglePK = true; cs.Value += "obj => new " + entity.RpName + Environment.NewLine; cs.Value += GetIndent(3) + "{" + Environment.NewLine; cs.Value += GetIndent(4) + "IsNew = false," + Environment.NewLine; foreach (PropertyPoco property in entity.Properties) { if (property.IsPK && isSinglePK) cs.Value += GetIndent(4) + EntityWithPkIdPropertyName + " = obj." + property.DcName + "," + Environment.NewLine; else { if (property.IsFK) cs.Value += GetIndent(4) + GetIdPropertyName(property.RpName) + " = obj." + property.DcName + "," + Environment.NewLine; else cs.Value += GetIndent(4) + property.RpName + " = obj." + property.DcName + "," + Environment.NewLine; } } cs.Value += GetIndent(3) + "}"; result.Expression = cs; method.Statements.Add(result); return method; }
private static CodeTypeDeclaration GetRepository(EntityPoco entity) { CodeTypeDeclaration ct = new CodeTypeDeclaration(entity.RpName + RepositoryClassNameSuffix) { IsClass = true, TypeAttributes = TypeAttributes.Public }; //Базовый тип CodeTypeReference type = new CodeTypeReference(RepositoryBaseClassName); type.TypeArguments.Add(entity.RpName); type.TypeArguments.Add(entity.DcFullName); ct.BaseTypes.Add(type); ct.Members.Add(GetRepositoryConstructor()); ct.Members.Add(GetRepositoryStaticConverterMethod(entity)); ct.Members.Add(GetRepositoryConvertorMethod(entity, ct.Name)); ct.Members.Add(GetRepositoryStaticPkConditionMethod(entity)); ct.Members.Add(GetRepositoryPkConditionMethod(entity, ct.Name)); ct.Members.Add(GetRepositoryStaticUpdateDbEntryMethod(entity)); ct.Members.Add(GetRepositoryUpdateDbEntryMethod(entity, ct.Name)); ct.Members.Add(GetRepositoryStaticUpdateEntryMethod(entity)); ct.Members.Add(GetRepositoryUpdateEntryMethod(entity, ct.Name)); return ct; }
private static CodeMemberMethod GetRepositoryConvertorMethod(EntityPoco entity, string repositoryName) { CodeMemberMethod method = new CodeMemberMethod { Attributes = MemberAttributes.Override | MemberAttributes.Family, Name = RepositoryBaseConvertorMethodName, ReturnType = new CodeTypeReference("System.Linq.Expressions.Expression") }; CodeTypeReference type = new CodeTypeReference("System.Func"); type.TypeArguments.Add(entity.DcFullName); type.TypeArguments.Add(entity.RpName); method.ReturnType.TypeArguments.Add(type); method.Statements.Add( new CodeMethodReturnStatement( new CodeMethodInvokeExpression( new CodeMethodReferenceExpression( new CodeTypeReferenceExpression(repositoryName), RepositoryBaseStaticConverterMethodName)))); return method; }
private static CodeTypeConstructor GetEntityStaticConstructor(EntityPoco entity) { CodeTypeConstructor ctor = new CodeTypeConstructor(); CodeTypeReferenceExpression type = new CodeTypeReferenceExpression(DataErrorInfoHelperClassName); CodeMethodInvokeExpression invoke = new CodeMethodInvokeExpression(type, DataErrorInfoHelperInitTypeMethodName, new CodeTypeOfExpression(entity.RpName)); ctor.Statements.Add(invoke); return ctor; }
private static CodeTypeDeclaration GetEntity(EntityPoco entity) { CodeTypeDeclaration ct = new CodeTypeDeclaration(entity.RpName) { IsClass = true, TypeAttributes = TypeAttributes.Public, IsPartial = true }; CodeTypeReference type; bool isSinglePK = false; if (entity.Properties.Count(p => p.IsPK) == 1) { isSinglePK = true; PropertyPoco property = entity.Properties.Single(p => p.IsPK); type = new CodeTypeReference(EntityWithPKClassName); type.TypeArguments.Add(property.Type); } else type = new CodeTypeReference(EntityClassName); ct.BaseTypes.Add(type); ct.Members.Add(GetEntityStaticConstructor(entity)); CodeConstructor ctor = new CodeConstructor { Attributes = MemberAttributes.Public }; ct.Members.Add(ctor); if (isSinglePK) { foreach (PropertyPoco property in entity.Properties.Where(p => !p.IsPK)) GetEntityProperty(ct, ctor, property); } else { foreach (PropertyPoco property in entity.Properties) GetEntityProperty(ct, ctor, property); } //if (ctor.Statements.Count > 0) // ct.Members.Add(ctor); return ct; }
private static void GetDMRepository(CodeTypeDeclaration dm, EntityPoco entity) { CodeMemberField field = new CodeMemberField { Attributes = MemberAttributes.Private, Name = GetBackFieldName(GetPluralForm(entity.RpName)), Type = new CodeTypeReference(RepositoryInterfaceName) }; field.Type.TypeArguments.Add(entity.RpName); dm.Members.Add(field); CodeMemberProperty property = new CodeMemberProperty { Attributes = MemberAttributes.Public | MemberAttributes.Final, Name = GetPluralForm(entity.RpName), HasGet = true, HasSet = false, Type = new CodeTypeReference(RepositoryInterfaceName), }; property.Type.TypeArguments.Add(entity.RpName); property.GetStatements.Add( new CodeMethodReturnStatement( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), GetBackFieldName(GetPluralForm(entity.RpName))))); property.SetStatements.Add( new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), GetBackFieldName(GetPluralForm(entity.RpName))), new CodePropertySetValueReferenceExpression())); dm.Members.Add(property); }
private static CodeMemberProperty GetDMInterfaceRepository(EntityPoco entity) { CodeMemberProperty member = new CodeMemberProperty { Attributes = MemberAttributes.Public, Name = GetPluralForm(entity.RpName), HasGet = true, HasSet = false, Type = new CodeTypeReference(RepositoryInterfaceName) }; member.Type.TypeArguments.Add(entity.RpName); return member; }
private static CodeMemberMethod GetRepositoryUpdateEntryMethod(EntityPoco entity, string repositoryName) { const string dbEntityParameterName = "dbEntity"; const string entityParameterName = "entity"; CodeMemberMethod method = new CodeMemberMethod { Attributes = MemberAttributes.Override | MemberAttributes.Family, Name = RepositoryBaseUpdateEntryMethodName }; method.Parameters.Add(new CodeParameterDeclarationExpression(entity.DcFullName, dbEntityParameterName)); method.Parameters.Add(new CodeParameterDeclarationExpression(entity.RpName, entityParameterName)); method.Statements.Add( new CodeMethodInvokeExpression( new CodeMethodReferenceExpression( new CodeTypeReferenceExpression(repositoryName), RepositoryBaseStaticUpdateEntryMethodName), new CodeVariableReferenceExpression(dbEntityParameterName), new CodeVariableReferenceExpression(entityParameterName))); return method; }