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;
        }