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; }
/// <summary> /// Реализация для команды AddCheckValue /// </summary> /// <param name="property">Свойство</param> private void AddCheckValueExecute(PropertyPoco property) { property.CheckValues.Add(new CheckValuePoco()); }
/// <summary> /// Реализация для команды RemoveProperty /// </summary> /// <param name="property">Свойство</param> private void RemovePropertyExecute(PropertyPoco property) { EntityPoco selectedEntity = (EntityPoco) CollectionViewSource.GetDefaultView(RepositoryModel.Entities).CurrentItem; selectedEntity.Properties.Remove(property); }
private static void GetMemberAttributes(CodeTypeMember member, PropertyPoco prop) { CodeAttributeDeclaration validationAttr = new CodeAttributeDeclaration( PropertyValidationAttributeName, new CodeAttributeArgument(new CodePrimitiveExpression(prop.DisplayName)), new CodeAttributeArgument(PropertyValidationNotNullPropertyName, new CodePrimitiveExpression(prop.NotNull))); if (prop.UseMaxValue) { validationAttr.Arguments.Add(new CodeAttributeArgument(PropertyValidationMaxValuePropertyName, new CodePrimitiveExpression(prop.MaxValue))); validationAttr.Arguments.Add(new CodeAttributeArgument(PropertyValidationIsMaxStrictPropertyName, new CodePrimitiveExpression(prop.IsMaxValueStrict))); } if (prop.UseMinValue) { validationAttr.Arguments.Add(new CodeAttributeArgument(PropertyValidationMinValuePropertyName, new CodePrimitiveExpression(prop.MinValue))); validationAttr.Arguments.Add(new CodeAttributeArgument(PropertyValidationIsMinStrictPropertyName, new CodePrimitiveExpression(prop.IsMinValueStrict))); } if (prop.IsFK) validationAttr.Arguments.Add(new CodeAttributeArgument(PropertyValidationIsFKPropertyName, new CodePrimitiveExpression(true))); if (prop.StringLength > 0) validationAttr.Arguments.Add(new CodeAttributeArgument(PropertyValidationStringLengthPropertyName, new CodePrimitiveExpression(prop.StringLength))); foreach (CheckValuePoco checkValue in prop.CheckValues) member.CustomAttributes.Add( new CodeAttributeDeclaration(PropertyCheckValueAttributeName, new CodeAttributeArgument(new CodePrimitiveExpression(checkValue.Value)))); member.CustomAttributes.Add(validationAttr); }
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('_', ' '); } } } } } } }
private static void GetEntityRefProperty(CodeTypeDeclaration ct, CodeConstructor ctor, PropertyPoco prop) { #region ID //const PropertyName CodeMemberField propName = new CodeMemberField { Attributes = MemberAttributes.Public | MemberAttributes.Const, Name = GetPropertyNameWithPropertyName(GetIdPropertyName(prop.RpName)), InitExpression = new CodePrimitiveExpression(GetIdPropertyName(prop.RpName)), Type = new CodeTypeReference("System.String") }; ct.Members.Add(propName); propName.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, prop.RpName)); propName.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, GetIdPropertyName(prop.RpName))); //partial method OnIDChanged string onIDPropertyChangedMethodName = string.Format(EntityPartialOnPropertyChangedNameStringFormat, GetPropertyNameWithPropertyName(GetIdPropertyName(prop.RpName))); ct.Members.Add(new CodeSnippetTypeMember(GetIndent(2) + "partial void " + onIDPropertyChangedMethodName + "();")); //back Field CodeMemberField backField = new CodeMemberField { Attributes = MemberAttributes.Private, Type = new CodeTypeReference(prop.Type), Name = GetBackFieldName(GetIdPropertyName(prop.RpName)) }; ct.Members.Add(backField); //Property CodeMemberProperty property = new CodeMemberProperty { Attributes = MemberAttributes.Public | MemberAttributes.Final, Name = GetIdPropertyName(prop.RpName), Type = new CodeTypeReference(prop.Type), }; property.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), backField.Name))); property.SetStatements.Add( new CodeConditionStatement( new CodePropertyReferenceExpression( new CodeThisReferenceExpression(), prop.RpName + EntityRefHasValueSuffix), new CodeThrowExceptionStatement( new CodeObjectCreateExpression( RepositoryExceptionClassName, new CodePrimitiveExpression(string.Format("{0} не может быть изменнено, т.к. {1} имеет установленное значение", GetIdPropertyName(prop.RpName), prop.RpName)))))); property.SetStatements.Add( new CodeConditionStatement( new CodeBinaryOperatorExpression( new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), backField.Name), CodeBinaryOperatorType.IdentityEquality, new CodePropertySetValueReferenceExpression()), new CodeMethodReturnStatement())); property.SetStatements.Add( new CodeAssignStatement( new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), backField.Name), new CodePropertySetValueReferenceExpression())); property.SetStatements.Add( new CodeMethodInvokeExpression( new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), EntityRaisePropertyChangedFunctionName), new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(ct.Name), propName.Name))); property.SetStatements.Add( new CodeMethodInvokeExpression( new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), onIDPropertyChangedMethodName))); property.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, GetIdPropertyName(prop.RpName))); ct.Members.Add(property); #endregion #region EntityRef //EntityRef CodeMemberField backErField = new CodeMemberField { Attributes = MemberAttributes.Private, Name = GetBackFieldName(prop.RpName), Type = new CodeTypeReference(EntityRefClassName) }; backErField.Type.TypeArguments.Add(prop.FkEntityType); ct.Members.Add(backErField); backErField.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, string.Format("{0}<{1}>", EntityRefClassName, prop.RpName))); //HasValue CodeMemberProperty hasValueProperty = new CodeMemberProperty { Attributes = MemberAttributes.Public | MemberAttributes.Final, Name = prop.RpName + EntityRefHasValueSuffix, Type = new CodeTypeReference("System.Boolean"), HasSet = false }; hasValueProperty.GetStatements.Add( new CodeMethodReturnStatement( new CodePropertyReferenceExpression( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), backErField.Name), EntityRefHasValuePropertyName))); ct.Members.Add(hasValueProperty); //const PropertyName CodeMemberField erPropName = new CodeMemberField { Attributes = MemberAttributes.Public | MemberAttributes.Const, Name = GetPropertyNameWithPropertyName(prop.RpName), InitExpression = new CodePrimitiveExpression(prop.RpName), Type = new CodeTypeReference("System.String") }; ct.Members.Add(erPropName); //partial method OnIDChanged string onPropertyChangedMethodName = string.Format(EntityPartialOnPropertyChangedNameStringFormat, prop.RpName); ct.Members.Add(new CodeSnippetTypeMember(GetIndent(2) + "partial void " + onPropertyChangedMethodName + "();")); //property CodeMemberProperty erProperty = new CodeMemberProperty { Attributes = MemberAttributes.Public | MemberAttributes.Final, Name = prop.RpName, Type = new CodeTypeReference(prop.FkEntityType) }; erProperty.GetStatements.Add( new CodeConditionStatement( new CodeBinaryOperatorExpression( new CodeBinaryOperatorExpression( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), backField.Name), CodeBinaryOperatorType.IdentityInequality, new CodeDefaultValueExpression(new CodeTypeReference(prop.Type))), CodeBinaryOperatorType.BooleanAnd, new CodeBinaryOperatorExpression( new CodePropertyReferenceExpression( new CodeThisReferenceExpression(), prop.RpName + EntityRefHasValueSuffix), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(false))), new CodeThrowExceptionStatement( new CodeObjectCreateExpression( RepositoryExceptionClassName, new CodePrimitiveExpression(string.Format("{0} не имеет установленное значение", prop.RpName)))))); erProperty.GetStatements.Add( new CodeMethodReturnStatement( new CodePropertyReferenceExpression( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), backErField.Name), EntityRefEntityPropertyName))); const string oldValueProp = "oldValue"; const string propChangedEvent = "PropertyChanged"; const string FkEntityPkName = "ID"; //NOTE: так как составные внешние ключи не поддерживаются, то ссылка идет на несоставной первичный ключ. Его имя всегда ID erProperty.SetStatements.Add( new CodeVariableDeclarationStatement(prop.FkEntityType, oldValueProp) { InitExpression = new CodePropertyReferenceExpression( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), backErField.Name), EntityRefEntityPropertyName) }); erProperty.SetStatements.Add(new CodeConditionStatement( new CodeBinaryOperatorExpression( new CodePropertyReferenceExpression( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), backErField.Name), EntityRefHasValueSuffix), CodeBinaryOperatorType.BooleanAnd, new CodeBinaryOperatorExpression( new CodeVariableReferenceExpression(oldValueProp), CodeBinaryOperatorType.ValueEquality, new CodePropertySetValueReferenceExpression())), new CodeMethodReturnStatement())); erProperty.SetStatements.Add(new CodeConditionStatement( new CodeBinaryOperatorExpression( new CodeVariableReferenceExpression(oldValueProp), CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)), new CodeRemoveEventStatement( new CodeVariableReferenceExpression(oldValueProp), propChangedEvent, new CodeMethodReferenceExpression( new CodeThisReferenceExpression(), prop.RpName + PropertyChangedSuffix)))); erProperty.SetStatements.Add( new CodeAssignStatement( new CodePropertyReferenceExpression( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), backErField.Name), EntityRefEntityPropertyName), new CodePropertySetValueReferenceExpression())); erProperty.SetStatements.Add(new CodeConditionStatement( new CodeBinaryOperatorExpression( new CodePropertySetValueReferenceExpression(), CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)), new CodeStatement[] { new CodeAssignStatement( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), backField.Name), new CodePropertyReferenceExpression( new CodePropertySetValueReferenceExpression(), FkEntityPkName)), new CodeAttachEventStatement( new CodePropertySetValueReferenceExpression(), propChangedEvent, new CodeMethodReferenceExpression( new CodeThisReferenceExpression(), prop.RpName + PropertyChangedSuffix)) }, new CodeStatement[] { new CodeAssignStatement( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), backField.Name), new CodeDefaultValueExpression(new CodeTypeReference(prop.Type))) })); erProperty.SetStatements.Add( new CodeMethodInvokeExpression( new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), EntityRaisePropertyChangedFunctionName), new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(ct.Name), erPropName.Name))); erProperty.SetStatements.Add( new CodeMethodInvokeExpression( new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), EntityRaisePropertyChangedFunctionName), new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(ct.Name), propName.Name))); property.SetStatements.Add( new CodeMethodInvokeExpression( new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), onPropertyChangedMethodName))); GetMemberAttributes(erProperty, prop); ct.Members.Add(erProperty); erProperty.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, string.Format("{0}<{1}>", EntityRefClassName, prop.RpName))); #endregion #region Methods ct.Members.Add(GetEntityPropertyChangedMethod(prop)); CodeMemberMethod setEntityMethod = GetSetEntityMethod(prop, ct.Name); ct.Members.Add(setEntityMethod); setEntityMethod.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, prop.RpName)); #endregion #region ctor CodeAssignStatement initEntityRef = new CodeAssignStatement( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), backErField.Name), new CodeObjectCreateExpression( backErField.Type)); ctor.Statements.Add(initEntityRef); #endregion }
private static CodeMemberMethod GetEntityPropertyChangedMethod(PropertyPoco prop) { const string senderParam = "sender"; const string eventArgsParam = "e"; CodeMemberMethod method = new CodeMemberMethod { Attributes = MemberAttributes.Family | MemberAttributes.Final, Name = prop.RpName + PropertyChangedSuffix }; method.Parameters.Add(new CodeParameterDeclarationExpression("System.Object", senderParam)); method.Parameters.Add(new CodeParameterDeclarationExpression("System.ComponentModel.PropertyChangedEventArgs", eventArgsParam)); method.Statements.Add( new CodeConditionStatement( new CodeBinaryOperatorExpression( new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(eventArgsParam), "PropertyName"), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression("ID")), //NOTE: так как составные внешние ключи не поддерживаются, то ссылка идет не составной первичный ключ. Его имя всегда ID new CodeAssignStatement( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), GetBackFieldName(GetIdPropertyName(prop.RpName))), new CodePropertyReferenceExpression( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), prop.RpName), "ID")))); return method; }
private static void GetEntityProperty(CodeTypeDeclaration ct, CodeConstructor ctor, PropertyPoco prop) { if (!prop.IsFK) GetSimpleEntityProperty(ct, prop); else GetEntityRefProperty(ct, ctor, prop); }
private static void GetSimpleEntityProperty(CodeTypeDeclaration ct, PropertyPoco prop) { string propType = prop.CreateNullable ? prop.Type + "?" : prop.Type; //const PropertyName CodeMemberField propName = new CodeMemberField { Attributes = MemberAttributes.Public | MemberAttributes.Const, Name = GetPropertyNameWithPropertyName(prop.RpName), InitExpression = new CodePrimitiveExpression(prop.RpName), Type = new CodeTypeReference("System.String") }; ct.Members.Add(propName); propName.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, prop.RpName)); //partial method OnChanged string onPropertyChangedMethodName = string.Format(EntityPartialOnPropertyChangedNameStringFormat, prop.RpName); ct.Members.Add(new CodeSnippetTypeMember(GetIndent(2) + "partial void " + onPropertyChangedMethodName + "();")); //back Field CodeMemberField backField = new CodeMemberField { Attributes = MemberAttributes.Private, Type = new CodeTypeReference(propType), Name = GetBackFieldName(prop.RpName) }; ct.Members.Add(backField); //Property CodeMemberProperty property = new CodeMemberProperty { Attributes = MemberAttributes.Public | MemberAttributes.Final, Name = prop.RpName, Type = new CodeTypeReference(propType), }; GetMemberAttributes(property, prop); property.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), backField.Name))); property.SetStatements.Add(new CodeConditionStatement( new CodeBinaryOperatorExpression( new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), backField.Name), CodeBinaryOperatorType.IdentityEquality, new CodePropertySetValueReferenceExpression()), new CodeMethodReturnStatement())); property.SetStatements.Add( new CodeAssignStatement( new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), backField.Name), new CodePropertySetValueReferenceExpression())); property.SetStatements.Add( new CodeMethodInvokeExpression( new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), EntityRaisePropertyChangedFunctionName), new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(ct.Name), propName.Name))); property.SetStatements.Add( new CodeMethodInvokeExpression( new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), onPropertyChangedMethodName))); property.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, prop.RpName)); ct.Members.Add(property); }
private static CodeMemberMethod GetSetEntityMethod(PropertyPoco prop, string thisType) { CodeMemberMethod method = new CodeMemberMethod { Attributes = MemberAttributes.Public | MemberAttributes.Final, Name = "Set" + prop.RpName, ReturnType = new CodeTypeReference(thisType) }; method.Parameters.Add( new CodeParameterDeclarationExpression(prop.FkEntityType, GetParameterName(prop.RpName))); method.Statements.Add( new CodeAssignStatement( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), prop.RpName), new CodeVariableReferenceExpression(GetParameterName(prop.RpName)))); method.Statements.Add(new CodeMethodReturnStatement(new CodeThisReferenceExpression())); return method; }