csharp REST呼叫C#承载令牌POST

RestPost.cs
//make request body
dynamic packet = mkPacket(parameters);
string ActivityId = "";
var client = new RestClient(endpoint + "/apiEndPoint");
RestRequest request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer " + token);
request.AddHeader("Content-Type", "application/json");
//post request body
request.AddParameter("undefined", packet, ParameterType.RequestBody);
request.Timeout = 5000;
IRestResponse response = client.Execute(request);
if (response.IsSuccessful)
{
    try
    {
      //parse the response object
        dynamic obj = JObject.Parse(response.Content);
    }
    catch (Exception ex)
    {
        ActivityId = ex.GetBaseException().ToString();
        log.Error($"Error writing to iMIS - Parsing Content -{ex.GetBaseException().ToString()}");
        throw ex;
    }
}
else
{
    ActivityId = response.Content.ToString();
    log.Error($"Error writing to iMIS - Response unsuccessful");
    throw new Exception("Error in method - writing Activity");
}

csharp REST呼叫C#承载令牌GET

Rest.cs
var client = new RestClient(endpoint + "/apiURL");
var request = new RestRequest(Method.GET);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("Content-Type", "application/json");
//if it needs a bearer token
request.AddHeader("Authorization", "Bearer " + token);

try
{
    IRestResponse response = client.Execute(request);
    string responseStatus = " ";
    
    if (response.IsSuccessful)
    {
        try
        {
          //cast response into an object
        }
        catch (Exception ex)
        {
            responseStatus = ex.GetBaseException().ToString();
            log.Error($"Error parsing response from iMIS -{ex.ToString()}");
        }
    }
    else
    {
        responseStatus = response.Content.ToString();
        log.Error($"Response not successful");
    }
}
catch (Exception ex)
{
    log.Error($"Error fetching from iMIS -{ex.ToString()}");
    throw ex;
}

csharp 强类型配置文件ASP CORE 2_2

JwtSettings.cs
// class
public class JwtSettings
{
	public string Secret { get; set; }
	public string Issuer { get; set; }
	public int TokenDurationInMinutes { get; set; }
}

// config file
"JwtSettings": {
    "Secret": "Ceci est la cle permettant d'encrypter les tokens JWTs emis par le serveur",
    "Issuer": "BacASable",
    "TokenDurationInMinutes": "1"
  }

// Strongly type
services.Configure<JwtSettings>(jwtSettingsSection);
var jwtSettings = jwtSettingsSection.Get<JwtSettings>();

services.AddSingleton(resolver => resolver.GetRequiredService<IOptions<JwtSettings>>().Value);

// get just values directly
Configuration["JwtSettings:Secret"];

csharp 自动映射配置ASP CORE 2_2

file
// Install package
Install-Package AutoMapper -Version 9.0.0
Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection -Version 7.0.0

// Configure method in startup.cs
services.AddAutoMapper(typeof(AutoMapperProfile));

//configure mapper AutoMapperProfile
public class AutoMapperProfile : Profile
	{
		public AutoMapperProfile()
		{
			CreateMap<User, UserDto>();
			CreateMap<UserDto, User>();
		}
	}

csharp 为ASP CORE 2_2配置IIdentyUser

file
// 1. Create a model that inherit from Microsoft.AspNetCore.Identity.IdentityUser

public class User : Microsoft.AspNetCore.Identity.IdentityUser
  {
    public string Nom { get; set; }
    public string Prenom { get; set; }
  }
  
  // 2.Create a datacontext that inherits from typed IdentityDbContext<User>
  public class DataContext : IdentityDbContext<User>
  {
    public DataContext(DbContextOptions options) : base(options)
    {

    }
  }
  
  // 3. COnfigure startup file
  services.AddIdentity<User, IdentityRole>(conf =>
			{
				conf.User.RequireUniqueEmail = true;
				conf.Password.RequiredLength = 6;
			}).AddEntityFrameworkStores<DataContext>().AddDefaultTokenProviders();
			
	// class to be injected in order to access the store
	UserManager<User>, UserRole<User>
	
//apply migration
add-migration MyFirstMigration
Update-Database
	
dotnet ef migrations add MyFirstMigration
dotnet ef database update

csharp CSHARP

CSHARP

copy-directory.cs
private static void copyDirectory(string sourceDirName, string destDirName, bool copySubDirs)
{
	DirectoryInfo dir = new DirectoryInfo(sourceDirName);

	if (!dir.Exists)
	{
		throw new DirectoryNotFoundException(
			"Source directory does not exist or could not be found: "
			+ sourceDirName);
	}

	if (!Directory.Exists(destDirName))
	{
		Directory.CreateDirectory(destDirName);
	}

	FileInfo[] files = dir.GetFiles();
	foreach (FileInfo file in files)
	{
		string temppath = Path.Combine(destDirName, file.Name);
		file.IsReadOnly = false;
		file.CopyTo(temppath, true);
	}

	if (copySubDirs)
	{
		DirectoryInfo[] dirs = dir.GetDirectories();
		foreach (DirectoryInfo subdir in dirs)
		{
			string temppath = Path.Combine(destDirName, subdir.Name);
			copyDirectory(subdir.FullName, temppath, copySubDirs);
		}
	}
}

csharp 版权

版权说明

copyrightSnippet.js
/************************************************************************
*
*    Copyright         Copyright 2019 ITECH ELECTRONIC CO.,LTD
*    File Name:        VMAComponentConverterRepository
*    Description:    VMA 控件转换库
*    此模块只处理与VMA 控件 相关的逻辑,其中包含VMA 控件的初始化,属性
*    变化,UI变化等
*
*    Version:       V 0.0.0.1
*    Author:            William-Joshua
*    Create Time:    2019-08-29
*
*************************************************************************/

csharp 选项<T>类

选项<T>类

Option.cs
//
// Copyright 2019 Scott Simontis
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//


using System;
using System.Collections.Generic;
using System.Linq;

namespace Ssimontis.Domain {
    public abstract class Option<T> {
        public static implicit operator Option<T>(T value) => new Some<T>(value);
        public static implicit operator Option<T>(None none) => new None<T>();

        public abstract Option<TResult> Map<TResult>(Func<T, TResult> map);
        public abstract Option<TResult> MapOptional<TResult>(Func<T, Option<TResult>> map);

        public abstract T Reduce(T whenNone);
        public abstract T Reduce(Func<T> whenNone);

        public Option<TNew> OfType<TNew>() where TNew : class =>
            this is Some<T> some && typeof(TNew).IsAssignableFrom(typeof(T))
                ? (Option<TNew>) new Some<TNew>(some.Content as TNew)
                : None.Value;
    }

    public sealed class Some<T> : Option<T>, IEquatable<Some<T>> {
        public T Content { get; }

        public Some(T value) {
            Content = value;
        }

        public static implicit operator T(Some<T> some) => some.Content;

        public override Option<TResult> Map<TResult>(Func<T, TResult> map) => map(Content);
        public override Option<TResult> MapOptional<TResult>(Func<T, Option<TResult>> map) => map(Content);

        public override T Reduce(T whenNone) => Content;
        public override T Reduce(Func<T> whenNone) => Content;

        public bool Equals(Some<T> other) {
            if (ReferenceEquals(null, other)) {
                return false;
            }

            return ReferenceEquals(this, other) || EqualityComparer<T>.Default.Equals(Content, other.Content);
        }

        public override bool Equals(object obj) => ReferenceEquals(this, obj) || obj is Some<T> other && Equals(other);

        public override int GetHashCode() => EqualityComparer<T>.Default.GetHashCode(Content);

        public static bool operator ==(Some<T> left, Some<T> right) => Equals(left, right);

        public static bool operator !=(Some<T> left, Some<T> right) => !Equals(left, right);
    }

    public sealed class None<T> : Option<T>, IEquatable<None<T>>, IEquatable<None> {
        public override Option<TResult> Map<TResult>(Func<T, TResult> map) => None.Value;
        public override Option<TResult> MapOptional<TResult>(Func<T, Option<TResult>> map) => None.Value;

        public override T Reduce(T whenNone) => whenNone;
        public override T Reduce(Func<T> whenNone) => whenNone();

        public override bool Equals(object obj) =>
        !(obj is null) && ((obj is None<T>) || (obj is None));

        public override int GetHashCode() => 0;

        public bool Equals(None<T> other) => true;

        public bool Equals(None other) => true;

        public static bool operator ==(None<T> a, None<T> b) =>
            (a is null && b is null) || (!(a is null) && a.Equals(b));

        public static bool operator !=(None<T> a, None<T> b) => !(a == b);
    }

    public sealed class None : IEquatable<None> {
        public static None Value { get; } = new None();

        private None() { }
        public bool Equals(None other) => true;

        public override bool Equals(object obj) => ReferenceEquals(this, obj) || obj is None other && Equals(other);

        public override int GetHashCode() => 0;

        public static bool operator ==(None left, None right) => Equals(left, right);

        public static bool operator !=(None left, None right) => !Equals(left, right);
    }

    public static class ObjectExtensions {
        public static Option<T> When<T>(this T obj, bool condition) =>
            condition ? (Option<T>) new Some<T>(obj) : None.Value;

        public static Option<T> When<T>(this T obj, Predicate<T> selector) => obj.When(selector(obj));

        public static Option<T> NoneIfNull<T>(this T obj) => obj.When(!(obj is null));
    }

    public static class EnumerableExtensions {
        public static Option<T> FirstOrNone<T>(this IEnumerable<T> sequence) =>
            sequence.Select(x => (Option<T>) new Some<T>(x)).DefaultIfEmpty(None.Value).First();

        public static Option<T> FirstOrNone<T>(this IEnumerable<T> sequence, Func<T, bool> predicate) =>
            sequence.Where(predicate).FirstOrNone();

        public static IEnumerable<TResult> SelectOptional<T, TResult>(
            this IEnumerable<T> sequence, Func<T, Option<TResult>> map) =>
            sequence.Select(map).OfType<Some<TResult>>().Select(some => some.Content);
    }

    public static class DictionaryExtensions {
        public static Option<TValue> TryGetValue<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key) =>
            dictionary.TryGetValue(key, out TValue value) ? (Option<TValue>) new Some<TValue>(value) : None.Value;
    }
}

csharp 使用Caliburn在一个窗口中分隔视图

[链接](https://rachel53461.wordpress.com/2011/12/18/navigation-with-mvvm-2/)<br/> <br/> [LINK](https://stackoverflow.com/questions / 12206120 / window-vs-page-vs-usercontrol-for-wpf-navigation)<br/> <br/> [LINK](https://caliburnmicro.com/documentation/cheat-sheet)<br/>

ShellView.xaml
<Window x:Class="MyProject.Views.ShellView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:CaliburnMicroTest.ViewModels"
        xmlns:v="clr-namespace:CaliburnMicroTest.Views"
        xmlns:cal="http://www.caliburnproject.org" >

  <!--ADDING VIEWS AND VIEWMODELS-->
    <Window.Resources>
        <DataTemplate DataType="{x:Type vm:Page1ViewModel }" >
            <v:Page1View />
        </DataTemplate>
        <DataTemplate DataType="{x:Type vm:Page2ViewModel }">
            <v:Page2View />
        </DataTemplate>
    </Window.Resources>
    
    <DockPanel>
        <!--NAVIGATION BUTTONS-->
        <Border DockPanel.Dock="Left">
            <ItemsControl ItemsSource="{Binding PageViewModels}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Button cal:Message.Attach="ChangeViewModel($this)" Content="{Binding Name}" />
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>            
        </Border>

        <ContentControl Content="{Binding CurrentPageViewModel}" />
    </DockPanel>
</Window>
ShellViewModel.cs
using System.Collections.Generic;
using System.Linq;

namespace MyProject.ViewModels 
{
    public class ShellViewModel : Caliburn.Micro.PropertyChangedBase, IShell
    {
        IViewModel _currentPageViewModel;
        List<IViewModel> _pageViewModels = new List<IViewModel>();

        public ShellViewModel()
        {
            _pageViewModels.Add(new Page1ViewModel());
            _pageViewModels.Add(new Page2ViewModel());

            CurrentPageViewModel = PageViewModels[0];
        }

        public List<IViewModel> PageViewModels
        {
            get => _pageViewModels == null ? new List<IViewModel>() : _pageViewModels;
        }

        public IViewModel CurrentPageViewModel
        {
            get => _currentPageViewModel;
            set
            {
                if (_currentPageViewModel != value)
                {
                    _currentPageViewModel = value;
                    NotifyOfPropertyChange(() => CurrentPageViewModel);
                }
            }
        }
        
        public void ChangeViewModel(IViewModel viewModel)
        {
            if (!PageViewModels.Contains(viewModel))
            {
                PageViewModels.Add(viewModel);
            }
            CurrentPageViewModel = PageViewModels.FirstOrDefault(vm => vm == viewModel);
        }
    }
}
IViewModel.cs
namespace CaliburnMicroTest.ViewModels
{
    public interface IViewModel
    {
        string Name { get; set; }
    }
}

csharp EFCore数据库上下文扩展

efcore_extension
// 首先请自觉nuget拉一下包 Microsoft.EntityFrameworkCore.Relational
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Linq;
using System.Reflection;

namespace BKY.Data
{

    /// <summary>
    /// 数据库查询语句
    /// </summary>
    public class DbContextSqlQueryCommand
    {
        /// <summary>
        /// 使用不含参数的查询语句
        /// </summary>
        /// <param name="query"></param>
        public DbContextSqlQueryCommand(string query)
        {
            Query = query;
        }
        /// <summary>
        /// 使用包含参数的查询语句
        /// </summary>
        /// <param name="query"></param>
        public DbContextSqlQueryCommand(string query, object @params)
        {
            Query = query;
            Parameters = @params;
        }
        /// <summary>
        /// 查询语句
        /// </summary>
        public string Query { get; set; }
        /// <summary>
        /// 参数
        /// </summary>
        public object Parameters { get; set; }
    }

    /// <summary>
    /// 数据库查询语句集合
    /// </summary>
    public class DbContextSqlQueryCommands
    {
        /// <summary>
        /// 数据库为SqlServer时使用的查询语句
        /// </summary>
        public DbContextSqlQueryCommand Sql { get; set; }
        /// <summary>
        /// 数据库为MySql时使用的查询语句
        /// </summary>
        public DbContextSqlQueryCommand MySql { get; set; }
        /// <summary>
        /// 数据库为InMemory时使用的查询语句
        /// </summary>
        public DbContextSqlQueryCommand InMemory { get; set; }
        /// <summary>
        /// 数据库为Sqlite时使用的查询语句
        /// </summary>
        public DbContextSqlQueryCommand Sqlite { get; set; }
    }

    /// <summary>
    /// 数据库类型
    /// </summary>
    public enum DbContextType
    {
        InMemory = 0,
        SqlServer = 1,
        MySql = 2,
        Sqlite = 3,
    }

    /// <summary>
    /// EF上下文扩展
    /// </summary>
    public static class DbContextExtensions
    {
        //拼接参数
        private static void combineParams(DbContextType type, ref DbCommand command, object @params = null)
        {
            if (@params != null)
            {
                Type paramType;
                string prefix;
                switch (type)
                {
                    case DbContextType.InMemory:
                        throw new Exception("未实现的数据库类型");
                    case DbContextType.SqlServer:
                        paramType = typeof(SqlParameter);
                        prefix = "@";
                        break;
                    default:
                        throw new Exception("未实现的数据库类型");
                }
                foreach (var param in @params.GetType().GetProperties())
                {
                    var paramItem = Activator.CreateInstance(paramType, $"{prefix}{param.Name}", (object)param.GetValue(@params));
                    command.Parameters.Add(paramItem);
                }
            }
        }
        //创建命令(同时返回连接符)
        private static DbCommand createCommand(DbContext context, DbContextSqlQueryCommands commands, out DbConnection connection)
        {
            var conn = context.Database.GetDbConnection();
            connection = conn;
            conn.Open();
            var cmd = conn.CreateCommand();
            if (commands.Sql != null && context.Database.IsSqlServer())
            {
                cmd.CommandText = commands.Sql.Query;
                combineParams(DbContextType.SqlServer, ref cmd, commands.Sql.Parameters);
            }
            else if (commands.InMemory != null)
            {
                throw new NotImplementedException();
            }
            return cmd;
        }

        /// <summary>
        /// 执行sql语句,返回受影响行数
        /// </summary>
        /// <param name="context">EF上下文</param>
        /// <param name="commands">数据库查询语句集合</param>
        /// <returns>受影响行数</returns>
        public static int Exec(this DbContext context, DbContextSqlQueryCommands commands)
        {
            var command = createCommand(context, commands, out var conn);
            var rsl = command.ExecuteNonQuery();
            conn.Close();
            return rsl;
        }

        /// <summary>
        /// 查询数据库
        /// </summary>
        /// <param name="context">EF上下文</param>
        /// <param name="commands">数据库查询语句集合</param>
        /// <returns>数据DataTable</returns>
        public static DataTable Query(this DbContext context, DbContextSqlQueryCommands commands)
        {
            var command = createCommand(context, commands, out var conn);
            var reader = command.ExecuteReader();
            DataTable dt = new DataTable();
            dt.Load(reader);
            reader.Close();
            conn.Close();
            return dt;
        }

        /// <summary>
        /// 查询数据库,返回多个查询结果集
        /// </summary>
        /// <param name="context">EF上下文</param>
        /// <param name="commands">数据库查询语句集合</param>
        /// <returns>数据DataSet</returns>
        public static DataSet QuerySet(this DbContext context, DbContextSqlQueryCommands commands)
        {
            var dt = Query(context, commands);
            var ds = new DataSet();
            ds.Tables.Add(dt);
            return ds;
        }

        /// <summary>
        /// 查询数据库,返回IEnumerable的强类型数据
        /// </summary>
        /// <typeparam name="T">查询结果类型</typeparam>
        /// <param name="context">EF上下文</param>
        /// <param name="commands">数据库查询语句集合</param>
        /// <returns>IEnumerable的强类型数据</returns>
        public static IEnumerable<T> Query<T>(this DbContext context, DbContextSqlQueryCommands commands)
        {
            var dt = Query(context, commands);
            return dt.ToEnumerable<T>();
        }

        /// <summary>
        /// 查询数据库,返回第一条数据
        /// </summary>
        /// <param name="context">EF上下文</param>
        /// <param name="commands">数据库查询语句集合</param>
        /// <returns>查询到的第一条数据或null</returns>
        public static DataRow QueryOne(this DbContext context, DbContextSqlQueryCommands commands)
        {
            var dt = Query(context, commands);
            return dt.Rows.Count > 0 ? dt.Rows[0] : null;
        }

        /// <summary>
        /// 查询数据库,返回第一条强类型数据
        /// </summary>
        /// <typeparam name="T">查询结果类型</typeparam>
        /// <param name="context">EF上下文</param>
        /// <param name="commands">数据库查询语句集合</param>
        /// <returns>查询到的第一条强类型数据</returns>
        public static T QueryOne<T>(this DbContext context, DbContextSqlQueryCommands commands)
        {
            var dr = QueryOne(context, commands);
            return dr.ToObject<T>();
        }

        /// <summary>
        /// 查询数据库,返回唯一数据
        /// </summary>
        /// <param name="context">EF上下文</param>
        /// <param name="commands">数据库查询语句集合</param>
        /// <returns>查询到的唯一数据</returns>
        public static object QueryObject(this DbContext context, DbContextSqlQueryCommands commands)
        {
            var command = createCommand(context, commands, out var conn);
            var rsl = command.ExecuteScalar();
            conn.Close();
            return rsl;
        }

        /// <summary>
        /// 查询数据库,返回唯一强类型数据
        /// </summary>
        /// <typeparam name="T">查询结果类型</typeparam>
        /// <param name="context">EF上下文</param>
        /// <param name="commands">数据库查询语句集合</param>
        /// <returns>查询到的唯一强类型数据</returns>
        public static T QueryObject<T>(this DbContext context, DbContextSqlQueryCommands commands)
        {
            return (T)QueryObject(context, commands);
        }
    }

    /// <summary>
    /// 数据相关扩展
    /// </summary>
    public static class DataExtensions
    {
        //从属性列表为DataTable创建列
        private static void createColumns(DataTable table, PropertyInfo[] piArr)
        {
            table.Columns.Clear();
            foreach (var pi in piArr)
            {
                table.Columns.Add(pi.Name, pi.PropertyType);
            }
        }

        //用obj的属性填充row
        private static void fillDataRow(DataRow row, object obj, PropertyInfo[] piArr)
        {
            foreach (var pi in piArr)
            {
                row[pi.Name] = pi.GetValue(obj);
            }
        }

        //用row的栏填充obj
        public static void fillObject<T>(T obj, DataRow row, PropertyInfo[] piArr)
        {
            foreach (var pi in piArr)
            {
                try
                {
                    pi.SetValue(obj, row[pi.Name]);
                }
                catch
                {
                }
            }
        }

        /// <summary>
        /// 从类型为DataTable创建Columns
        /// </summary>
        /// <param name="table">DataTable对象</param>
        /// <param name="type">作为创建模板的类型</param>
        public static void CreateColumsFromType(this DataTable table, Type type)
        {
            PropertyInfo[] piArr = type.GetProperties();
            createColumns(table, piArr);
        }

        /// <summary>
        /// 从object为DataTable创建Columns
        /// </summary>
        /// <param name="table">DataTable对象</param>
        /// <param name="obj">作为创建模板的object</param>
        public static void CreateColumsFromObject(this DataTable table, object obj)
        {
            CreateColumsFromType(table, obj.GetType());
        }

        /// <summary>
        /// 将DataRow转换为强类型
        /// </summary>
        /// <typeparam name="T">要转换为的强类型</typeparam>
        /// <param name="row">要转换的DataRow对象</param>
        /// <returns>转换后的强类型对象</returns>
        public static T ToObject<T>(this DataRow row)
        {
            if (row == null)
            {
                return default(T);
            }
            var obj = Activator.CreateInstance<T>();
            PropertyInfo[] piArr = typeof(T).GetProperties();
            fillObject(obj, row, piArr);
            return obj;
        }

        /// <summary>
        /// 将对象转换为DataRow对象
        /// </summary>
        /// <param name="obj">要转换的对象</param>
        /// <returns>转换后的DataRow对象</returns>
        public static DataRow ToDataRow(this object obj)
        {
            if (obj == null)
            {
                return null;
            }
            PropertyInfo[] piArr = obj.GetType().GetProperties();
            DataTable dt = new DataTable();
            createColumns(dt, piArr);

            DataRow row = dt.NewRow();
            fillDataRow(row, obj, piArr);

            return row;
        }

        /// <summary>
        /// 将对象转换为属于指定DataTable的DataRow对象
        /// </summary>
        /// <param name="table">属于的table</param>
        /// <param name="obj">要转换的对象</param>
        /// <returns>转换后的属于指定DataTable的DataRow对象</returns>
        public static DataRow ToDataRow(this object obj, DataTable table)
        {
            if (obj == null)
            {
                return null;
            }
            PropertyInfo[] piArr = obj.GetType().GetProperties();
            createColumns(table, piArr);

            DataRow row = table.NewRow();
            fillDataRow(row, obj, piArr);

            return row;
        }


        /// <summary>
        /// 将DataTable转换为IEnumerable的强类型对象
        /// </summary>
        /// <typeparam name="T">要转换为的强类型</typeparam>
        /// <param name="table">要转换的DataTable对象</param>
        /// <returns>转换后的IEnumerable的强类型对象</returns>
        public static IEnumerable<T> ToEnumerable<T>(this DataTable table)
        {
            List<T> list = new List<T>();
            PropertyInfo[] piArr = typeof(T).GetProperties();
            foreach (DataRow row in table.Rows)
            {
                var obj = Activator.CreateInstance<T>();
                fillObject(obj, row, piArr);
                list.Add(obj);
            }
            return list.AsEnumerable<T>();
        }

        /// <summary>
        /// 将IEnumerable的强类型对象转换为DataTable
        /// </summary>
        /// <typeparam name="T">要转换的强类型</typeparam>
        /// <param name="objArr">要转换的IEnumerable的强类型对象</param>
        /// <returns>转换后的DataTable对象</returns>
        public static DataTable ToDataTable<T>(this IEnumerable<T> objArr)
        {
            DataTable dt = new DataTable();
            PropertyInfo[] piArr = typeof(T).GetProperties();
            createColumns(dt, piArr);

            foreach (var obj in objArr)
            {
                DataRow row = dt.NewRow();
                fillDataRow(row, obj, piArr);
                dt.Rows.Add(row);
            }
            return dt;
        }

        /// <summary>
        /// 将DataSet转换为IEnumerable的IEnumerable的强类型对象
        /// </summary>
        /// <typeparam name="T">要转换为的强类型</typeparam>
        /// <param name="set">要转换的DataSet对象</param>
        /// <returns>转换后的IEnumerable的IEnumerable的强类型对象</returns>
        public static IEnumerable<IEnumerable<T>> ToEnumerableEnumerable<T>(this DataSet set)
        {
            List<IEnumerable<T>> rsl = new List<IEnumerable<T>>();
            PropertyInfo[] piArr = typeof(T).GetProperties();

            foreach (DataTable dt in set.Tables)
            {
                List<T> list = new List<T>();
                foreach (DataRow row in dt.Rows)
                {
                    var obj = Activator.CreateInstance<T>();
                    fillObject(obj, row, piArr);
                    list.Add(obj);
                }
                rsl.Add(list.AsEnumerable<T>());
            }
            return rsl.AsEnumerable<IEnumerable<T>>();
        }
    }
}