C#中如何实现ftp图片上传功能的图文代码分享(必看)

互联网 17-6-18
这篇文章主要介绍了C# 中实现ftp 图片上传功能(多快好省),需要的朋友可以参考下

前言

此篇讲到的是图片上传功能,每个网站必定会有这样类似的功能,上传文件、上传图片等等。那么接下来,看看我们EF+uploadfile+ftp如何玩转上传图片吧

效果预览

具体实现

一个简单数据库 只有一个主键Id,一个身份证正面路径和一个身份证背面路径三个字段。

首先呢,我们把实体类新建好如下:

public class ImageModel:BaseEntity   {    /// <summary>    /// 用户Id    /// </summary>    public int ID { get; set; }    /// <summary>    ///身份证正面相对路径    /// </summary>    public string IDProofFront { get; set; }    /// <summary>    ///身份证背面相对路径    /// </summary>    public string IDProofBack { get; set; }   }

其中 我们将身份信息实体继承自BaseEntity,我们看看BaseEntity里面是什么东东,代码如下:

public abstract partial class BaseEntity   {    public override bool Equals(object obj)    {     return Equals(obj as BaseEntity);    }    private Type GetUnproxiedType()    {     return GetType();    }    public virtual bool Equals(BaseEntity other)    {     if (other == null)      return false;     if (ReferenceEquals(this, other))      return true;     return false;    }    public override int GetHashCode()    {     return base.GetHashCode();    }    public static bool operator ==(BaseEntity x, BaseEntity y)    {     return Equals(x, y);    }    public static bool operator !=(BaseEntity x, BaseEntity y)    {     return !(x == y);    }   }

这里,我们将BaseEntity定义成一个抽象类,里面包含一些静态方法和重载方法

======================回到HTML=======

我们先回过头来讲页面,上面演示的是一个很简单的单页面,HTML代码如下:

 <form enctype="multipart/form-data" id="form" action="/Home/UpLoadImage" method="post">    <p class="full_w" style="margin-top: 100px; margin-left: 30%; width: 800px;">     <p class="h_title"> <b>用户上传的文件</b></p>     <p class="entry">      步骤: <span class="red" style="color: red">(上传资料必须是bmp,gif,jpg,jpeg,png类型,不能大于2M)</span>      <ol>       <li>先按『选择』键选择上传文件;</li>       <li>按『上传』键上传文件;</li>       <li>按『保存』键保存文件;</li>      </ol>     </p>     <p class="entry">      <p class="sep"></p>     </p>     <p class="entry">      <p id="wrapper" style="text-align: center; position: relative;">       <p class="form-group">        <input id="uploadfile" type="file" value="浏览..." class="file" name="FileName" data-upload-url="#" style="position: absolute; top: 0; right: 0; min-width: 100%; min-height: 100%; text-align: right; opacity: 0; background: none repeat scroll 0 0 transparent; cursor: inherit; display: block;" />       </p>      </p>     </p>     <table>      <tbody>       <tr>        <td class="entry">身份证正面</td>        <td>         @if (Model == null || Model.ID == null || string.IsNullOrEmpty(Model.IDProofFront))         {          <a href="javascript:void(0);" rel="external nofollow" rel="external nofollow" target="_blank" class="winView">           <img style="border: none; width: 150px; height: 100px" src="/img/noupload.png" />          </a>         }         else         {          <a href="@(ViewBag.pathSrc + Model.IDProofFront)" rel="external nofollow" target="_blank"class="winView" >           <img style="border: none; width: 150px; height: 100px" src="@(ViewBag.pathSrc + Model.IDProofFront)" />          </a>         }         @Html.HiddenFor(m => m.IDProofFront)         @Html.HiddenFor(m => m.ID)        </td>        <td>         <a href="javascript:void(0)" rel="external nofollow" rel="external nofollow" class="easyui-linkbutton btnFinleUP" data-op="1" data-type="image">上传</a>        </td>       </tr>       <tr>        <td class="entry">身份证背面</td>        <span id="lblinfosi" style="color: Green"></span>        <td>         @if (Model == null || Model.ID == null || string.IsNullOrEmpty(Model.IDProofBack))         {          <a href="javascript:void(0);" rel="external nofollow" rel="external nofollow" target="_blank" class="winView">           <img style="border: none; width: 150px; height: 100px" src="/img/noupload.png" />          </a>         }         else         {          <a href="@(ViewBag.pathSrc + Model.IDProofBack)" rel="external nofollow" target="_blank" class="winView" >           <img style="border: none; width: 150px; height: 100px" src="@(ViewBag.pathSrc + Model.IDProofBack)" />          </a>         }         @Html.HiddenFor(m => m.IDProofBack)        </td>        <td>         <a href="javascript:void(0)" rel="external nofollow" rel="external nofollow" class="easyui-linkbutton btnFinleUP" data-op="2" data-type="image">上传</a>        </td>       </tr>      </tbody>     </table>     <p class="entry">      <button class="button" name="btnSaveAll" value="保存" id="btnSaveAll" style="height: 30px; width: 80px; text-align: center;">保存</button>      <a href="/Home/Index" rel="external nofollow" style="height: 30px; text-align: center; width: 80px; background: #ffffff; border: 1px solid #DCDCDC; border-radius: 2px; color: #444444; cursor: pointer; display: inline-block; font: 700 11px Tahoma, Arial, sans-serif; margin-right: 10px; padding: 7px 12px 7px 12px; position: relative; text-decoration: none; text-shadow: 0px 1px 0px #FFFFFF;">返回</a>     </p>    </p>   </form>

现在我们看页面将会毫无样式,所以我们先引用下样式,这里引用了bootstrap 和一个 style2.css ,引入样式后 界面如下:

其中,关于选择框是用了一个js单独封装起来了,是代码中的zh.js,代码如下:

/*!   * FileInput Chinese Translations   *   * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or   * any HTML markup tags in the messages must not be converted or translated.   *   * @see http://github.com/kartik-v/bootstrap-fileinput   * @author kangqf <kangqingfei@gmail.com>   *   * NOTE: this file must be saved in UTF-8 encoding.   */  (function ($) {   "use strict";   $.fn.fileinputLocales['zh'] = {    fileSingle: '文件',    filePlural: '个文件',    browseLabel: '选择 …',    removeLabel: '移除',    removeTitle: '清除选中文件',    cancelLabel: '取消',    cancelTitle: '取消进行中的上传',    uploadLabel: '上传',    uploadTitle: '上传选中文件',    msgNo: '没有',    msgNoFilesSelected: '',    msgCancelled: '取消',    msgZoomModalHeading: '详细预览',    msgSizeTooSmall: 'File "{name}" (<b>{size} KB</b>) is too small and must be larger than <b>{minSize} KB</b>.',    msgSizeTooLarge: '文件 "{name}" (<b>{size} KB</b>) 超过了允许大小 <b>{maxSize} KB</b>.',    msgFilesTooLess: '你必须选择最少 <b>{n}</b> {files} 来上传. ',    msgFilesTooMany: '选择的上传文件个数 <b>({n})</b> 超出最大文件的限制个数 <b>{m}</b>.',    msgFileNotFound: '文件 "{name}" 未找到!',    msgFileSecured: '安全限制,为了防止读取文件 "{name}".',    msgFileNotReadable: '文件 "{name}" 不可读.',    msgFilePreviewAborted: '取消 "{name}" 的预览.',    msgFilePreviewError: '读取 "{name}" 时出现了一个错误.',    msgInvalidFileName: 'Invalid or unsupported characters in file name "{name}".',    msgInvalidFileType: '不正确的类型 "{name}". 只支持 "{types}" 类型的文件.',    msgInvalidFileExtension: '不正确的文件扩展名 "{name}". 只支持 "{extensions}" 的文件扩展名.',    msgFileTypes: {     'image': 'image',     'html': 'HTML',     'text': 'text',     'video': 'video',     'audio': 'audio',     'flash': 'flash',     'pdf': 'PDF',     'object': 'object'    },    msgUploadAborted: '该文件上传被中止',    msgUploadThreshold: 'Processing...',    msgUploadEmpty: 'No valid data available for upload.',    msgValidationError: '验证错误',    msgLoading: '加载第 {index} 文件 共 {files} …',    msgProgress: '加载第 {index} 文件 共 {files} - {name} - {percent}% 完成.',    msgSelected: '{n} {files} 选中',    msgFoldersNotAllowed: '只支持拖拽文件! 跳过 {n} 拖拽的文件夹.',    msgImageWidthSmall: '宽度的图像文件的"{name}"的必须是至少{size}像素.',    msgImageHeightSmall: '图像文件的"{name}"的高度必须至少为{size}像素.',    msgImageWidthLarge: '宽度的图像文件"{name}"不能超过{size}像素.',    msgImageHeightLarge: '图像文件"{name}"的高度不能超过{size}像素.',    msgImageResizeError: '无法获取的图像尺寸调整。',    msgImageResizeException: '错误而调整图像大小。<pre>{errors}</pre>',    msgAjaxError: 'Something went wrong with the {operation} operation. Please try again later!',    msgAjaxProgressError: '{operation} failed',    ajaxOperations: {     deleteThumb: 'file delete',     uploadThumb: 'single file upload',     uploadBatch: 'batch file upload',     uploadExtra: 'form data upload'    },    dropZoneTitle: '拖拽文件到这里 …<br>支持多文件同时上传',    dropZoneClickTitle: '<br>(或点击{files}按钮选择文件)',    fileActionSettings: {     removeTitle: '删除文件',     uploadTitle: '上传文件',     zoomTitle: '查看详情',     dragTitle: '移动 / 重置',     indicatorNewTitle: '没有上传',     indicatorSuccessTitle: '上传',     indicatorErrorTitle: '上传错误',     indicatorLoadingTitle: '上传 ...'    },    previewZoomButtonTitles: {     prev: '预览上一个文件',     next: '预览下一个文件',     toggleheader: '缩放',     fullscreen: '全屏',     borderless: '无边界模式',     close: '关闭当前预览'    }   };  })(window.jQuery);

好了,界面大概就整成这样子,现在需要我们实现功能了。首先用JS将上传控件初始化一下:

//上传控件初始化   function initFileUpload() {    $("#uploadfile").fileinput({     //uploadExtraData: { kvId: '10' },     language: 'zh', //设置语言      showUpload: false, //是否显示上传按钮     uploadAsync: true, //默认异步上传     showRemove: false,     autoReplace: true,     maxFileCount: 1,     maxFileSize: 10240,     dropZoneTitle: '拖拽文件到这里 …<br>仅限.pdf, .jpg, .jpeg, .gif',     enctype: 'multipart/form-data',     fileActionSettings: { uploadClass: "hidden", zoomClass: "hidden", removeClass: "hidden" },     allowedFileExtensions: ['jpg', 'png', 'gif', 'pdf'],//接收的文件后缀     msgFilesTooMany: "选择上传的文件数量({n}) 超过允许的最大数值{m}!",     uploadUrl: "/FileUpload/FileUpLoad", //上传的地址    }).on("filebatchselected", function (event, files) {     $(".file-preview-success").remove();    })    $("#uploadfile").on("fileuploaded", function (event, data, previewId, index) {     console.log("accountData 初始化后 FileOpt" + accountData);     console.log("accountData.FileOpt " + accountData.FileOpt);     var obj = data.response;     if (obj.Status != 500 && obj.Data != undefined) {      var src = accountData.PathSrc + obj.Data.FileName;      showName = obj.Data.FileName;      //alert(showName);      var pId = accountData.PId;      var fileObj = undefined;      var field = "";      var isPdf = false;      debugger;      if (accountData.FileOpt == 1) {       fileObj = $("#IDProofFront");       //$("#PersonInfo_OldIDFile").val(obj.Data.FileName);       field = "IDProofFront";       fileObj.val(obj.Data.FileName);      } else if (accountData.FileOpt == 2) {       fileObj = $("#IDProofBack");       field = "IDProofBack";       $("#IDProofBack").val(showName);       fileObj.val(obj.Data.FileName);      }      //fileObj = $("#IDProofFront");      //$("#IDProofFront").val(obj.Data.FileName);      //field = "IDProofFront";      //fileObj.val(obj.Data.FileName);      fileObj.prev().attr("href", src);      src = isPdf == true ? "/Content/images/PDF.png" : src;      fileObj.prev().find("img").attr("src", src);     } else {      console.error(obj.Data);     }    });    $('#uploadfile').on('filesuccessremove', function (event, id) {    });    $('#uploadfile').on('fileerror', function (event, data, msg) {    });    //上传    $(".btnFinleUP").click(function () {     var fileName = $("#uploadfile").val();     var obj = document.getElementById("uploadfile");     var type = $(this).attr("data-op");     //alert("当前点击的type是:" + type);     var fileType = $(this).attr("data-type");     var files = $("#uploadfile").fileinput("getFileStack");     if (files.length == 0) {      layer.msg('请选择要上传的文件', function () { });      return;     }     var array = fileType.split(",");     var selectType = files[0].type.toLowerCase();     var falg = false;     for (var i = 0; i < array.length; i++) {      if (selectType.indexOf(array[i]) == -1) {       falg = false;      } else       falg = true;      if (falg)       break;     }     if (!falg) {      layer.msg('只能选择' + fileType + ' 类型的文件', function () { });      return;     }     accountData.FileOpt = type;     $("#uploadfile").fileinput("upload");    });   }

然后再 加载页面的时候调用这个初始化即可

 $(function () {    initFileUpload();  })

FTP上传操作

注意,再initFileUpload方法中 上传了图片,会自动访问uploadUrl 这个url地址,存放图片,我们先看看这个action如何通过ftp上传指定服务器的。

FileUpLoad方法如下

/// <summary>    /// 通过ftp上传指定服务器    /// </summary>    /// <returns></returns>    public ActionResult FileUpLoad()    {     bool flag = false;     string msg = string.Empty;     int size = Convert.ToInt16(_fileSize) * 1024 * 1024;     try     {      Dictionary<string, string> fileDict = new Dictionary<string, string>();      for (int i = 0; i < Request.Files.Count; i++)      {       HttpPostedFileBase file = Request.Files[i];       string extension = Path.GetExtension(file.FileName);       string[] fileExtensions = _fileExtension.Split(';');       if (fileExtensions.Any(o => o.Equals(extension, StringComparison.OrdinalIgnoreCase)))       {        if (file.ContentLength <= size)        {         string fileName = string.Format("{0}_{1}", DateTime.Now.ToString("yyyyMMddHHmmssfff"), Path.GetFileName(file.FileName));         if (file.ContentLength <= 10 * 1024 * 1024)         {          byte[] buffer = new byte[file.ContentLength];          file.InputStream.Read(buffer, 0, file.ContentLength);          flag = FileUpLoad(buffer, file.FileName, out fileName, out msg);         }         else//图片压缩有问题>>         {          var stream = ImageHelper.GetPicThumbnail(file.InputStream, 40);          byte[] buffer = new byte[stream.Length];          stream.Read(buffer, 0, (int)stream.Length);          flag = FileUpLoad(buffer, file.FileName, out fileName, out msg);         }         fileDict.Add(Request.Files.AllKeys[i], fileName);        }        else        {         msg = string.Format("上传文件不能大于{0}M", _fileSize);        }       }       else       {        msg = string.Format("上传的文件类型不正确");       }      }      return Json(new { Result = "0", MSG = "" + msg, Data = fileDict });     }     catch (Exception ex)     {      return Json(new { Result = "0", MSG = "网络异常,请稍后再试" });     }    }

其中 _fileExtension _filePath _fileSize 是分别从配置文件中读取出来的如下:

private static string _fileExtension = ConfigurationManager.AppSettings["FileType"];    private readonly string _filePath = ConfigurationManager.AppSettings["UploadPath"];    private readonly string _fileSize = ConfigurationManager.AppSettings["FileSizem"];

方法中有一个 FileUpLoad 上传文件的方法 如下:

/// <summary>    /// 上传文件    /// </summary>    /// <param name="fileBytes"></param>    /// <param name="originalName"></param>    /// <param name="msg"></param>    /// <returns></returns>    protected bool FileUpLoad(byte[] fileBytes, string originalName, out string newFileName, out string msg)    {     msg = "";     newFileName = "";     try     {      FTPUpFile ftp = new FTPUpFile();      newFileName = ftp.UpFile(fileBytes, originalName);      if (string.IsNullOrEmpty(newFileName))      {       msg = "上传文件时出错!";       return false;      }      return true;     }     catch (Exception ex)     {      msg = ex.Message;      return false;     }    }

其中

FTPUpFile 是一个ftp上传文件帮助类,大家可以直接照搬 ,代码如下:

/// <summary>   /// FTP上传文件   /// </summary>   public class FTPUpFile   {    string Filetype = ConfigurationManager.AppSettings["FileType"];    string ipaddress = ConfigurationManager.AppSettings["IPaddress"];    string Username = ConfigurationManager.AppSettings["UserName"];    string Password = ConfigurationManager.AppSettings["Password"];    /// <summary>    /// FTP上传文件    /// </summary>    /// <param name="filename">上传文件路径</param>    /// <param name="ftpServerIP">FTP服务器的IP和端口</param>    /// <param name="ftpPath">FTP服务器下的哪个目录</param>    /// <param name="ftpUserID">FTP用户名</param>    /// <param name="ftpPassword">FTP密码</param>    public bool Upload(string filename, string ftpServerIP, string ftpPath, string ftpUserID, string ftpPassword)    {     FileInfo fileInf = new FileInfo(filename);     string uri = "ftp://" + ftpServerIP + "/" + ftpPath + "/" + fileInf.Name;     try     {      FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));      // ftp用户名和密码      reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);      reqFTP.KeepAlive = false;      // 指定执行什么命令      reqFTP.Method = WebRequestMethods.Ftp.UploadFile;      // 指定数据传输类型      reqFTP.UseBinary = true;      // 上传文件时通知服务器文件的大小      reqFTP.ContentLength = fileInf.Length;      //this.Invoke(InitUProgress, fileInf.Length);      // 缓冲大小设置为2kb      int buffLength = 4096;      byte[] buff = new byte[buffLength];      int contentLen;      // 打开一个文件流 (System.IO.FileStream) 去读上传的文件      FileStream fs = fileInf.OpenRead();      // 把上传的文件写入流      Stream strm = reqFTP.GetRequestStream();      contentLen = fs.Read(buff, 0, buffLength);      while (contentLen != 0)      {       strm.Write(buff, 0, contentLen);       contentLen = fs.Read(buff, 0, buffLength);      }      // 关闭两个流      strm.Close();      strm.Dispose();      fs.Close();      fs.Dispose();      return true;     }     catch (Exception ex)     {      return false;     }    }    /// <summary>    /// 新建目录    /// </summary>    /// <param name="ftpPath"></param>    /// <param name="dirName"></param>    public void MakeDir(string ftpPath, string dirName, string username, string password)    {     try     {      //实例化FTP连接      FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpPath + dirName));      // ftp用户名和密码      request.Credentials = new NetworkCredential(username, password);      // 默认为true,连接不会被关闭      request.KeepAlive = false;      //指定FTP操作类型为创建目录      request.Method = WebRequestMethods.Ftp.MakeDirectory;      //获取FTP服务器的响应      FtpWebResponse response = (FtpWebResponse)request.GetResponse();      response.Close();     }     catch (Exception ex)     {      //Respons     }    }    /// <summary>    /// 删除指定文件    /// </summary>    /// <param name="ftpPath"></param>    /// <param name="dirName"></param>    /// <param name="username"></param>    /// <param name="password"></param>    public void DeleteFile(string ftpPath, string username, string password)    {     try     {      // string uri = "ftp://" + ftpServerIP + "/" + ftpPath + "/" + fileInf.Name;      //ftpPath = "ftp://192.168.1.111:2005/2012-12-05/20121206O5CATICE.docx";      //password = "111";      //username = "yuanluluoli";      //实例化FTP连接      FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpPath));      request.Method = WebRequestMethods.Ftp.DeleteFile;      // ftp用户名和密码      request.Credentials = new NetworkCredential(username, password);      // 默认为true,连接不会被关闭      request.KeepAlive = false;      //获取FTP服务器的响应      FtpWebResponse response = (FtpWebResponse)request.GetResponse();      response.Close();     }     catch (Exception ex)     {      //Respons     }    }    /// <summary>    /// 检查目录是否存在    /// </summary>    /// <param name="ftpPath">要检查的目录的路径</param>    /// <param name="dirName">要检查的目录名</param>    /// <returns>存在返回true,否则false</returns>    public bool CheckDirectoryExist(string ftpPath, string dirName, string username, string password)    {     bool result = false;     try     {      //实例化FTP连接      FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpPath));      // ftp用户名和密码      request.Credentials = new NetworkCredential(username, password);      request.KeepAlive = false;      //指定FTP操作类型为创建目录      request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;      //获取FTP服务器的响应      FtpWebResponse response = (FtpWebResponse)request.GetResponse();      StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.Default);      StringBuilder str = new StringBuilder();      string line = sr.ReadLine();      while (line != null)      {       str.Append(line);       str.Append("|");       line = sr.ReadLine();      }      string[] datas = str.ToString().Split('|');      for (int i = 0; i < datas.Length; i++)      {       if (datas[i].Contains("<DIR>"))       {        int index = datas[i].IndexOf("<DIR>");        string name = datas[i].Substring(index + 5).Trim();        if (name == dirName)        {         result = true;         break;        }       }      }      sr.Close();      sr.Dispose();      response.Close();     }     catch (Exception)     {      return false;     }     return result;    }    /// <summary>    /// 上传文件    /// </summary>    /// <param name="buffer">文件的Byte数组</param>    /// <param name="originalName">文件原始名字(带后缀名)</param>    /// <param name="perStr">新文件名的前缀</param>    /// <returns></returns>    public string UpFile(byte[] buffer, string originalName, string perStr = "")    {     if (buffer == null || buffer.Length <= 0 || string.IsNullOrEmpty(originalName))      throw new ArgumentException("参数错误!");     string filePathstr = string.Empty;     string filepathsql = null;     try     {      string pathstr = perStr + DateTime.Now.ToString().Replace("/", "").Replace("-", "").Replace(":", "").Replace(" ", "");      string rodumlist = GeneralHelper.GetMixPwd(10);//10位随机数      filePathstr = "~/File/" + pathstr + rodumlist + Path.GetExtension(originalName);      //Stream sr = upfile.PostedFile.InputStream;      //byte[] file = new byte[sr.Length];      //sr.Read(file, 0, file.Length);      StreamWriter sw = new StreamWriter(HttpContext.Current.Server.MapPath(filePathstr));      sw.BaseStream.Write(buffer, 0, buffer.Length);      sw.Flush(); sw.Close();      // file.SaveAs(HttpContext.Current.Server.MapPath(filePathstr));//把文件上传到服务器的绝对路径上      bool check;      string ftpPath = DateTime.Now.ToString("yyyy-MM-dd");      string uri = @"ftp://" + ipaddress + "/";      //检查是否存在此目录文件夹      if (CheckDirectoryExist(uri, ftpPath, Username, Password))      {       //存在此文件夹就直接上传       check = Upload(HttpContext.Current.Server.MapPath(filePathstr), ipaddress, ftpPath, Username, Password);      }      else      {       MakeDir(uri, ftpPath, Username, Password);//创建       check = Upload(HttpContext.Current.Server.MapPath(filePathstr), ipaddress, ftpPath, Username, Password);      }      //成功就更新      if (check)      {       filepathsql = ftpPath + "/" + pathstr + rodumlist + Path.GetExtension(originalName);      }      //检查是否存在此文件      if (File.Exists(HttpContext.Current.Server.MapPath(filePathstr)))      {       File.Delete(HttpContext.Current.Server.MapPath(filePathstr));      }      return filepathsql;     }     catch (Exception ex)     {      File.Delete(HttpContext.Current.Server.MapPath(filePathstr));      throw ex;     }    }    /// <summary>    /// 上传文件    /// 不修改名字及后缀名    /// </summary>    /// <param name="originalFilePath">上传文件的绝对路径</param>    /// <returns></returns>    public string UpFile(string originalFilePath)    {     if (string.IsNullOrEmpty(originalFilePath))      throw new ArgumentException("参数错误!");     string filepathsql = null;     try     {      //检查是否存在此文件      if (!File.Exists(originalFilePath))       throw new Exception("文件不存在!");      //Stream sr = upfile.PostedFile.InputStream;      //byte[] file = new byte[sr.Length];      //sr.Read(file, 0, file.Length);      // file.SaveAs(HttpContext.Current.Server.MapPath(filePathstr));//把文件上传到服务器的绝对路径上      bool check;      string ftpPath = DateTime.Now.ToString("yyyy-MM-dd");      string uri = @"ftp://" + ipaddress + "/";      //检查是否存在此目录文件夹      if (CheckDirectoryExist(uri, ftpPath, Username, Password))      {       //存在此文件夹就直接上传       check = Upload(originalFilePath, ipaddress, ftpPath, Username, Password);      }      else      {       MakeDir(uri, ftpPath, Username, Password);//创建       check = Upload(originalFilePath, ipaddress, ftpPath, Username, Password);      }      //成功就更新      if (check)      {       filepathsql = ftpPath + "/" + Path.GetFileName(originalFilePath);      }      //检查是否存在此文件      if (File.Exists(originalFilePath))      {       File.Delete(originalFilePath);      }      return filepathsql;     }     catch (Exception ex)     {      //File.Delete(originalFilePath);      throw ex;     }    }    public string Ftp_Up(HtmlInputFile upfile)    {     //Encrypt En = new Encrypt();     string filePathstr = string.Empty;     string filepathsql = null;     try     {      string pathstr = DateTime.Now.ToString().Replace("/", "").Replace("-", "").Replace(":", "").Replace(" ", "");      string rodumlist = GeneralHelper.GetMixPwd(10);//10位随机数      filePathstr = "~/File/" + pathstr + rodumlist + Path.GetExtension(upfile.PostedFile.FileName);      Stream sr = upfile.PostedFile.InputStream;      byte[] file = new byte[sr.Length];      sr.Read(file, 0, file.Length);      StreamWriter sw = new StreamWriter(HttpContext.Current.Server.MapPath(filePathstr));      sw.BaseStream.Write(file, 0, file.Length);      sw.Flush(); sw.Close(); sr.Flush(); sr.Close();      // file.SaveAs(HttpContext.Current.Server.MapPath(filePathstr));//把文件上传到服务器的绝对路径上      bool check;      string ftpPath = DateTime.Now.ToString("yyyy-MM-dd");      string uri = @"ftp://" + ipaddress + "/";      //检查是否存在此目录文件夹      if (CheckDirectoryExist(uri, ftpPath, Username, Password))      {       //存在此文件夹就直接上传       check = Upload(HttpContext.Current.Server.MapPath(filePathstr), ipaddress, ftpPath, Username, Password);      }      else      {       MakeDir(uri, ftpPath, Username, Password);//创建       check = Upload(HttpContext.Current.Server.MapPath(filePathstr), ipaddress, ftpPath, Username, Password);      }      //成功就更新      if (check)      {       filepathsql = ftpPath + "/" + pathstr + rodumlist + Path.GetExtension(upfile.PostedFile.FileName);      }      //检查是否存在此文件      if (File.Exists(HttpContext.Current.Server.MapPath(filePathstr)))      {       File.Delete(HttpContext.Current.Server.MapPath(filePathstr));      }      return filepathsql;     }     catch (Exception)     {      File.Delete(HttpContext.Current.Server.MapPath(filePathstr));      return filepathsql;      // Response.Write("<script>alert(" + ex.Message + ");</script>");     }    }    /// <summary>    /// 上传    /// </summary>    /// <param name="file"></param>    /// <returns></returns>    public string Ftp_Up(HttpPostedFileBase postedFile)    {     string filePathstr = string.Empty;     string filepathsql = null;     try     {      string pathstr = DateTime.Now.ToString("yyyyMMddHHmmss");      string rodumlist = GeneralHelper.GetMixPwd(10);//10位随机数      string filename = System.IO.Path.GetFileName(postedFile.FileName);      string eExtension = Path.GetExtension(filename);      string strLocation = HttpContext.Current.Server.MapPath("~/File/");      filePathstr = strLocation + pathstr + rodumlist + eExtension;      postedFile.SaveAs(filePathstr);      bool check;      string ftpPath = DateTime.Now.ToString("yyyy-MM-dd");      string uri = @"ftp://" + ipaddress + "/";      //检查是否存在此目录文件夹      if (CheckDirectoryExist(uri, ftpPath, Username, Password))      {       //存在此文件夹就直接上传       check = Upload(filePathstr, ipaddress, ftpPath, Username, Password);      }      else      {       MakeDir(uri, ftpPath, Username, Password);//创建       check = Upload(filePathstr, ipaddress, ftpPath, Username, Password);      }      //成功就更新      if (check)      {       filepathsql = ftpPath + "/" + pathstr + rodumlist + eExtension;      }      //检查是否存在此文件      if (File.Exists(filePathstr))      {       File.Delete(filePathstr);      }      return filepathsql;     }     catch (Exception ex)     {      //检查是否存在此文件      if (File.Exists(filePathstr))      {       File.Delete(filePathstr);      }      return "";      // Response.Write("<script>alert(" + ex.Message + ");</script>");     }    }    /// <summary>    /// FTP下载文件在服务器目录    /// </summary>    /// <param name="pathname">本地保存目录路径和文件名称</param>    /// <param name="filename">FTP目录路径和文件名称</param>    /// <returns></returns>    public bool FileDown(string pathname, string filename)    {     string uri = "ftp://" + ipaddress + "/" + filename;     string FileName = pathname;//本地保存目录     //创建一个文件流     FileStream fs = null;     Stream responseStream = null;     try     {      //创建一个与FTP服务器联系的FtpWebRequest对象      FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri(uri));      //连接登录FTP服务器      request.Credentials = new NetworkCredential(Username, Password);      request.KeepAlive = false;      //设置请求的方法是FTP文件下载      request.Method = WebRequestMethods.Ftp.DownloadFile;      //获取一个请求响应对象      FtpWebResponse response = (FtpWebResponse)request.GetResponse();      //获取请求的响应流      responseStream = response.GetResponseStream();      //判断本地文件是否存在,如果存在,则打开和重写本地文件      if (File.Exists(FileName))       fs = File.Open(FileName, FileMode.Open, FileAccess.ReadWrite);      //判断本地文件是否存在,如果不存在,则创建本地文件      else      {       fs = File.Create(FileName);      }      if (fs != null)      {       int buffer_count = 65536;       byte[] buffer = new byte[buffer_count];       int size = 0;       while ((size = responseStream.Read(buffer, 0, buffer_count)) > 0)       {        fs.Write(buffer, 0, size);       }       fs.Flush();       fs.Close();       responseStream.Close();      }      return true;     }     catch (Exception ex)     {      return false;     }     finally     {      if (fs != null)       fs.Close();      if (responseStream != null)       responseStream.Close();     }    }    /// <summary>    /// 保存和上传图片    /// </summary>    /// <param name="imgtwo">需要上传图片</param>    /// <param name="date"></param>    /// <returns>文件路径</returns>    public string SaveUploadImg(Bitmap imgtwo)    {     string filePathstr = string.Empty;     string filepathsql = null;     try     {      string pathstr = DateTime.Now.ToString().Replace("/", "").Replace("-", "").Replace(":", "").Replace(" ", "");      string rodumlist = GeneralHelper.GetMixPwd(10);//10位随机数      filePathstr = "~/File/" + pathstr + rodumlist + ".jpg";      imgtwo.Save(HttpContext.Current.Server.MapPath(filePathstr));//把文件上传到服务器的绝对路径上      bool check;      string ftpPath = DateTime.Now.ToString("yyyy-MM-dd");      string uri = @"ftp://" + ipaddress + "/";      //检查是否存在此目录文件夹      if (CheckDirectoryExist(uri, ftpPath, Username, Password))      {       //存在此文件夹就直接上传       check = Upload(HttpContext.Current.Server.MapPath(filePathstr), ipaddress, ftpPath, Username, Password);      }      else      {       MakeDir(uri, ftpPath, Username, Password);//创建       check = Upload(HttpContext.Current.Server.MapPath(filePathstr), ipaddress, ftpPath, Username, Password);      }      //成功就更新      if (check)      {       filepathsql = ftpPath + "/" + pathstr + rodumlist + ".jpg";      }      //检查是否存在此文件      if (File.Exists(HttpContext.Current.Server.MapPath(filePathstr)))      {       File.Delete(HttpContext.Current.Server.MapPath(filePathstr));      }      imgtwo.Dispose();      return filepathsql;     }     catch (Exception ex)     {      File.Delete(HttpContext.Current.Server.MapPath(filePathstr));      return filepathsql;     }    }    #region    /// <summary>    /// 文件大小    /// </summary>    public bool _File_Length(int ContentLength)    {     bool length = false;     int FileLen = ContentLength;     if (FileLen > 2048 * 1024 == false)//不能超过2M     {      length = true;     }     return length;    }    #endregion    //用来获取文件类型    public bool File_PastFileName(string fileName)    {     //bmp, doc, docx, gif, jpg, jpeg, pdf, png, tif, tiff     bool isnot = true;     string ext = Path.GetExtension(fileName);     string[] type = Filetype.Split(';');     for (int i = 0; i < type.Length; i++)     {      if (type[i].ToLower() == ext.ToLower())      {       isnot = false;       break;      }     }     return isnot;    }   }

值得注意的是:帮助类中也从配置文件中读取了存放地址、文件类型、用户名、密码等必要信息。这个大家可以自己再配置文件中配置,配置好了如下所示:

 <add key="FileSizem" value="10"></add>   <add key="FileType" value=".bmp;.gif;.jpg;.jpeg;.png;.pdf" />   <!---本地测试-->   <add key="IPaddress" value="路径" />   <!--FTP上传文件的帐号-->   <add key="UserName" value="账号" />   <!--FTP上传文件的密码-->   <add key="Password" value="密码" />   <!--后台显示图片地址-->   <add key="PathSrc" value="路径" />

还有一个类是图片帮助类,代码如下:

public class ImageHelper   {    /// <summary>    /// 图片压缩    /// </summary>    /// <param name="sFile">原图路径</param>    /// <param name="dFile">保存路径</param>    /// <param name="flag">压缩质量(数字越小压缩率越高) 1-100</param>    /// <param name="dWidth">宽度</param>    /// <param name="dHeight">高度</param>    /// <returns></returns>    public static bool SavePicThumbnail(string sFile, string dFile, int flag, int dWidth = 0, int dHeight = 0)    {       System.Drawing.Image iSource = System.Drawing.Image.FromFile(sFile);     return SavePicThumbnail(dFile, flag, iSource, dWidth, dHeight);        }    /// <summary>    /// 图片压缩    /// </summary>    /// <param name="sFile">原图流</param>    /// <param name="dFile">保存路径</param>    /// <param name="flag">压缩质量(数字越小压缩率越高) 1-100</param>    /// <param name="dWidth">宽度</param>    /// <param name="dHeight">高度</param>    /// <returns></returns>    public static bool SavePicThumbnail(Stream stream, string dFile, int flag, int dWidth = 0, int dHeight = 0)    {       System.Drawing.Image iSource = System.Drawing.Image.FromStream(stream);     return SavePicThumbnail(dFile, flag, iSource, dWidth, dHeight);      }          #region GetPicThumbnail      public static Stream GetPicThumbnail(Stream stream ,int flag, int dWidth = 0, int dHeight = 0)    {     System.Drawing.Image iSource = System.Drawing.Image.FromStream(stream);     ImageFormat tFormat = iSource.RawFormat;     int sW = 0, sH = 0;     if (dHeight == 0 && dWidth == 0)     {      sW = iSource.Width;      sH = iSource.Height;     }     else if (dWidth != 0)     {      sW = dWidth;      sH = iSource.Height * dWidth / iSource.Width;     }     else if (dHeight != 0)     {      sH = dHeight;      sW = iSource.Width * dHeight / iSource.Height;     }     Bitmap ob = new Bitmap(sW, sH);     Graphics g = Graphics.FromImage(ob);     g.Clear(Color.WhiteSmoke);     g.CompositingQuality = CompositingQuality.HighQuality;     g.SmoothingMode = SmoothingMode.HighQuality;     g.InterpolationMode = InterpolationMode.HighQualityBicubic;     g.DrawImage(iSource, new Rectangle(0, 0, sW, sH), 0, 0, iSource.Width, iSource.Height, GraphicsUnit.Pixel);     g.Dispose();     //以下代码为保存图片时,设置压缩质量     EncoderParameters ep = new EncoderParameters();     long[] qy = new long[1];     qy[0] = flag;//设置压缩的比例1-100     EncoderParameter eParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qy);     ep.Param[0] = eParam;     MemoryStream ms = new MemoryStream();      try     {      ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();      ImageCodecInfo jpegICIinfo = null;      for (int x = 0; x < arrayICI.Length; x++)      {       if (arrayICI[x].FormatDescription.Equals("JPEG"))       {        jpegICIinfo = arrayICI[x];        break;       }      }      if (jpegICIinfo != null)      {       ob.Save(ms, jpegICIinfo, ep);//dFile是压缩后的新路径        }      else      {       ob.Save(ms, tFormat);      }            return stream;     }     catch     {      return null;     }     finally     {      iSource.Dispose();      ob.Dispose();     }    }        public static bool SavePicThumbnail(string dFile, int flag, System.Drawing.Image iSource, int dWidth = 0, int dHeight = 0)    {       ImageFormat tFormat = iSource.RawFormat;     int sW = 0, sH = 0;     if (dHeight == 0 && dWidth == 0)     {      sW = iSource.Width;      sH = iSource.Height;     }     else if (dWidth != 0)     {      sW = dWidth;      sH = iSource.Height * dWidth / iSource.Width;     }     else if (dHeight != 0)     {      sH = dHeight;      sW = iSource.Width * dHeight / iSource.Height;     }     Bitmap ob = new Bitmap(sW, sH);     Graphics g = Graphics.FromImage(ob);     g.Clear(Color.WhiteSmoke);     g.CompositingQuality = CompositingQuality.HighQuality;     g.SmoothingMode = SmoothingMode.HighQuality;     g.InterpolationMode = InterpolationMode.HighQualityBicubic;     g.DrawImage(iSource, new Rectangle(0, 0, sW, sH), 0, 0, iSource.Width, iSource.Height, GraphicsUnit.Pixel);     g.Dispose();     //以下代码为保存图片时,设置压缩质量     EncoderParameters ep = new EncoderParameters();     long[] qy = new long[1];     qy[0] = flag;//设置压缩的比例1-100     EncoderParameter eParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qy);     ep.Param[0] = eParam;     try     {      ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();      ImageCodecInfo jpegICIinfo = null;      for (int x = 0; x < arrayICI.Length; x++)      {       if (arrayICI[x].FormatDescription.Equals("JPEG"))       {        jpegICIinfo = arrayICI[x];        break;       }      }      if (jpegICIinfo != null)      {       ob.Save(dFile, jpegICIinfo, ep);//dFile是压缩后的新路径      }      else      {       ob.Save(dFile, tFormat);      }      return true;     }     catch     {      return false;     }     finally     {      iSource.Dispose();      ob.Dispose();     }    }    #endregion   }

然后我们通过在fileuploaded的回调函数中绑定url即可显示上传后的图片,效果如下图:

不过这个只是上传到ftp服务器上了,并没有保存到数据库,现在我们要做的就是通过EF的方式将上传的图片保存到数据库。

保存图片

首先我们要建一个操作的接口基类,并且还要约束成BaseEntity,代码如下

public interface IRepository<T> where T : BaseEntity   {    /// <summary>    /// 根据过滤条件,获取记录    /// </summary>    /// <param name="exp"></param>    /// <param name="isNoTracking">(默认不跟踪实体状态)使用NoTracking的查询会在性能方面得到改善</param>    /// <returns></returns>    IQueryable<T> Find(Expression<Func<T, bool>> exp = null, bool isNoTracking = true);    /// <summary>    /// 根据过滤条件,获取记录    /// </summary>    /// <param name="whereLambda"></param>    /// <param name="isNoTracking">(默认不跟踪实体状态)使用NoTracking的查询会在性能方面得到改善</param>    /// <param name="values"></param>    /// <returns></returns>    IQueryable<T> Find(string whereLambda = null, bool isNoTracking = true, params object[] values);    IQueryable<TEntity> OtherTable<TEntity>() where TEntity : BaseEntity;    IDbSet<TEntity> Set<TEntity>() where TEntity : BaseEntity;    /// <summary>    /// 判断记录是否存在    /// </summary>    /// <param name="exp"></param>    /// <returns></returns>    bool IsExist(Expression<Func<T, bool>> exp);    /// <summary>    /// 查找单个(如果没找到则返回为NULL)    /// </summary>    /// <param name="exp"></param>    /// <param name="isNoTracking">(默认不跟踪实体状态)使用NoTracking的查询会在性能方面得到改善</param>    /// <returns></returns>    T FindSingle(Expression<Func<T, bool>> exp, bool isNoTracking = true);    /// <summary>    /// 得到分页记录    /// </summary>    /// <param name="pageIndex">The pageindex.</param>    /// <param name="pageSize">The pagesize.</param>    /// <param name="total">总条数</param>    /// <param name="exp">条件谓词</param>    /// <param name="orderBy">排序,格式如:"Id"/"Id descending"</param>    IQueryable<T> Find(int pageIndex, int pageSize, out int total, Expression<Func<T, bool>> exp = null, string orderBy = "");    /// <summary>    /// 得到分页记录    /// </summary>    /// <param name="pageIndex">The pageindex.</param>    /// <param name="pageSize">The pagesize.</param>    /// <param name="total">总条数</param>    /// <param name="whereLambda">条件谓词</param>    /// <param name="orderBy">排序,格式如:"Id"/"Id descending"</param>    IQueryable<T> Find(int pageIndex, int pageSize, out int total, string whereLambda = "", string orderBy = "", params object[] values);    /// <summary>    /// 根据过滤条件获取记录数    /// </summary>    int GetCount(Expression<Func<T, bool>> exp = null);    /// <summary>    /// 添加实体    /// </summary>    /// <param name="entity">The entities.</param>    /// <param name="isComit">是否提交(true)</param>    /// <returns></returns>    int Add(T entity, bool isComit = true);    /// <summary>    /// 批量添加    /// </summary>    /// <param name="entity">The entities.</param>    /// <param name="isComit">是否提交(true)</param>    int Adds(List<T> entitis, bool isComit = true);    /// <summary>    /// 更新实体(会更新实体的所有属性)    /// </summary>    /// <param name="entity">The entities.</param>    /// <param name="isComit">是否提交(true)</param>    /// <returns></returns>    int Update(T entity, bool isComit = true);    /// <summary>    /// 删除实体    /// </summary>    /// <param name="entity">The entities.</param>    /// <param name="isComit">是否提交(true)</param>    /// <returns></returns>    int Delete(T entity, bool isComit = true);    /// <summary>    /// 实现按需要只更新部分更新    /// <para>如:Update(u =>u.Id==1,u =>new User{Name="ok"});</para>    /// </summary>    /// <param name="where">The where.</param>    /// <param name="entity">The entity.</param>    int Update(Expression<Func<T, bool>> where, Expression<Func<T, T>> entity);    /// <summary>    /// 批量按条件删除    /// </summary>    /// <param name="exp"></param>    int Delete(Expression<Func<T, bool>> exp);    /// <summary>    /// 对数据库执行给定的 DDL/DML 命令。    /// </summary>    /// <param name="sql">sql</param>    /// <param name="parameters">参数</param>    /// <returns></returns>    int ExecuteSqlCommand(string sql, params SqlParameter[] parameters);    /// <summary>    /// 执行SQL查询语句    /// </summary>    /// <param name="sql"></param>    /// <returns></returns>    DbRawSqlQuery<int> ExecuteSqlQuery(string sql);    /// <summary>    /// 执行原始的sql查询    /// </summary>    /// <typeparam name="TElement">返回的泛型类型</typeparam>    /// <param name="sql">sql</param>    /// <param name="parameters">参数</param>    /// <returns></returns>    IList<TElement> SqlQuery<TElement>(string sql, params SqlParameter[] parameters);    /// <summary>    /// 开启一个事务    /// </summary>    /// <param name="fun"></param>    bool BeginTransaction(Func<bool> fun);    /// <summary>    /// 执行SQL语句或存储过程    /// 返回Datatable数据集    /// </summary>    /// <param name="sql">SQL语句或存储过程 例如:exec usp_procedure</param>    /// <param name="parameters">参数列表</param>    /// <returns></returns>    DataTable SqlQueryForDataTable(string sql, DbParameter[] parameters);    /// <summary>    /// 返回Datatable数据集    /// </summary>    /// <param name="proName">存储过程名</param>    /// <param name="parameters">参数列表</param>    /// <returns></returns>    [Obsolete("此方法已过时,请改用SqlQueryForDataTable")]    DataTable ExecuteForDataTable(string proName, IDataParameter[] parameters);   }

然后需要实现这个基类接口,代码如下:

public class BaseRepository<T> : IRepository<T> where T : BaseEntity    {      private DbContext Context      {        get        {          DbContext db = (DbContext)CallContext.GetData("DbContext");          if (db == null)          {            db = new DbContext();            // db.Database.Log = o => LoggingHelper.Instance.Logging(LogLevel.Debug, o);            CallContext.SetData("DbContext", db);          }          return db;        }      }      /// <summary>      /// 根据过滤条件,获取记录      /// </summary>      /// <param name="exp"></param>      /// <param name="isNoTracking">(默认不跟踪实体状态)使用NoTracking的查询会在性能方面得到改善</param>      /// <returns></returns>      public IQueryable<T> Find(Expression<Func<T, bool>> exp = null, bool isNoTracking = true)      {        return Filter(exp, isNoTracking);      }      /// <summary>      /// 根据过滤条件,获取记录      /// </summary>      /// <param name="whereLambda"></param>      /// <param name="isNoTracking">(默认不跟踪实体状态)使用NoTracking的查询会在性能方面得到改善</param>      /// <param name="values"></param>      /// <returns></returns>      public IQueryable<T> Find(string whereLambda = null, bool isNoTracking = true, params object[] values)      {        return Filter(whereLambda, isNoTracking, values);      }      /// <summary>      /// 判断记录是否存在      /// </summary>      /// <param name="exp"></param>      /// <returns></returns>      public bool IsExist(Expression<Func<T, bool>> exp)      {        return Context.Set<T>().Any(exp);      }      /// <summary>      /// 查找单个(如果没找到则返回为NULL)      /// </summary>      /// <param name="exp"></param>      /// <param name="isNoTracking">(默认不跟踪实体状态)使用NoTracking的查询会在性能方面得到改善</param>      /// <returns></returns>      public T FindSingle(Expression<Func<T, bool>> exp, bool isNoTracking = true)      {        return Filter(exp, isNoTracking).FirstOrDefault();      }      /// <summary>      /// 得到分页记录      /// </summary>      /// <param name="pageIndex">The pageindex.</param>      /// <param name="pageSize">The pagesize.</param>      /// <param name="total">总条数</param>      /// <param name="exp">条件谓词</param>      /// <param name="orderBy">排序,格式如:"Id"/"Id descending"</param>      public IQueryable<T> Find(int pageIndex, int pageSize, out int total, Expression<Func<T, bool>> exp = null, string orderBy = "")      {        if (pageIndex < 1) pageIndex = 1;        var query = Filter(exp);        if (!string.IsNullOrEmpty(orderBy))          query = query.OrderBy(orderBy);        total = query.Count();        ///return query.Skip(pageSize * (pageIndex - 1)).Take(pageSize);        return null;      }      /// <summary>      /// 得到分页记录      /// </summary>      /// <param name="pageIndex">The pageindex.</param>      /// <param name="pageSize">The pagesize.</param>      /// <param name="total">总条数</param>      /// <param name="whereLambda">条件谓词</param>      /// <param name="orderBy">排序,格式如:"Id"/"Id descending"</param>      public IQueryable<T> Find(int pageIndex, int pageSize, out int total, string whereLambda = "", string orderBy = "", params object[] values)      {        if (pageIndex < 1) pageIndex = 1;        var query = Filter(whereLambda);        if (string.IsNullOrEmpty(orderBy))          query = query.OrderBy(orderBy);        total = query.Count();        // return query.Skip(pageSize * (pageIndex - 1)).Take(pageSize);        return null;      }      /// <summary>      /// 根据过滤条件获取记录数      /// </summary>      public int GetCount(Expression<Func<T, bool>> exp = null)      {        return Filter(exp).Count();      }      /// <summary>      /// 添加书体      /// </summary>      /// <param name="entity">The entities.</param>      /// <param name="isComit">是否提交(true)</param>      /// <returns></returns>      public int Add(T entity, bool isComit = true)      {        Context.Entry<T>(entity).State = System.Data.Entity.EntityState.Added;        return isComit ? Context.SaveChanges() : 0;      }      /// <summary>      /// 批量添加      /// </summary>      /// <param name="entity">The entities.</param>      /// <param name="isComit">是否提交(true)</param>      public int Adds(List<T> entitis, bool isComit = true)      {        foreach (T item in entitis)        {          Context.Entry<T>(item).State = System.Data.Entity.EntityState.Added;        }        return isComit ? Context.SaveChanges() : 0;      }      /// <summary>      /// 更新实体(会更新实体的所有属性)      /// </summary>      /// <param name="entity">The entities.</param>      /// <param name="isComit">是否提交(true)</param>      /// <returns></returns>      public int Update(T entity, bool isComit = true)      {        Context.Entry(entity).State = System.Data.Entity.EntityState.Modified;        return isComit ? Context.SaveChanges() : 0;      }      /// <summary>      /// 删除实体      /// </summary>      /// <param name="entity">The entities.</param>      /// <param name="isComit">是否提交(true)</param>      /// <returns></returns>      public int Delete(T entity, bool isComit = true)      {        Context.Set<T>().Remove(entity);        return isComit ? Context.SaveChanges() : 0;      }      /// <summary>      /// 实现按需要只更新部分更新      /// <para>如:Update(u =>u.Id==1,u =>new User{Name="ok"});</para>      /// </summary>      /// <param name="where">The where.</param>      /// <param name="entity">The entity.</param>      public int Update(Expression<Func<T, bool>> where, Expression<Func<T, T>> entity)      {        return Context.Set<T>().Where(where).Update(entity);      }      /// <summary>      /// 批量按条件删除      /// </summary>      /// <param name="exp"></param>      public int Delete(Expression<Func<T, bool>> exp)      {        return Context.Set<T>().Where(exp).Delete();      }      /// <summary>      /// 对数据库执行给定的 DDL/DML 命令。      /// </summary>      /// <param name="sql">sql</param>      /// <param name="parameters">参数</param>      /// <returns></returns>      public int ExecuteSqlCommand(string sql, params SqlParameter[] parameters)      {        return Context.Database.ExecuteSqlCommand(sql, parameters);      }      /// <summary>      /// 执行原始的sql查询      /// </summary>      /// <typeparam name="TElement">返回的泛型类型</typeparam>      /// <param name="sql">sql</param>      /// <param name="parameters">参数</param>      /// <returns></returns>      public IList<TElement> SqlQuery<TElement>(string sql, params SqlParameter[] parameters)      {        return Context.Database.SqlQuery<TElement>(sql, parameters).ToList();      }      public bool BeginTransaction(Func<bool> fun)      {        using (var trans = Context.Database.BeginTransaction())        {          try          {            var result = fun();            trans.Commit();            return result;          }          catch (Exception)          {            trans.Rollback();            return false;          }        }      }      private IQueryable<T> Filter(Expression<Func<T, bool>> exp = null, bool isNoTracking = true)      {        var dbSet = Context.Set<T>().AsQueryable();        if (exp != null)          dbSet = dbSet.Where(exp);        if (isNoTracking)          dbSet = dbSet.AsNoTracking();        return dbSet;      }      private IQueryable<T> Filter(string whereLambda = null, bool isNoTracking = true, params object[] values)      {        var dbSet = Context.Set<T>().AsQueryable();        if (whereLambda != null)          dbSet = dbSet.Where(whereLambda, values);        if (isNoTracking)          dbSet = dbSet.AsNoTracking();        return dbSet;      }      public IQueryable<T> Table      {        get        {          return Find(whereLambda: null);        }      }      public IQueryable<TEntity> OtherTable<TEntity>() where TEntity : BaseEntity      {        return Context.Set<TEntity>().AsNoTracking().AsQueryable();      }      public IDbSet<TEntity> Set<TEntity>() where TEntity : BaseEntity      {        return Context.Set<TEntity>();      }      /// <summary>      /// 执行SQL查询语句      /// </summary>      /// <param name="sql"></param>      /// <returns></returns>      public DbRawSqlQuery<int> ExecuteSqlQuery(string sql)      {        try        {          return Context.Database.SqlQuery<int>(sql);        }        catch (Exception ex)        {          throw ex;        }      }      /// <summary>      /// 执行SQL语句或存储过程      /// 返回Datatable数据集      /// </summary>      /// <param name="sql">SQL语句或存储过程 例如:exec usp_procedure</param>      /// <param name="parameters">参数列表</param>      /// <returns></returns>      public System.Data.DataTable SqlQueryForDataTable(string sql, params System.Data.Common.DbParameter[] parameters)      {        SqlConnection conn = new System.Data.SqlClient.SqlConnection();        try        {          conn = (SqlConnection)Context.Database.Connection;          if (conn.State != ConnectionState.Open)          {            conn.Open();          }          SqlCommand cmd = new SqlCommand();          StringBuilder sb = new StringBuilder(sql);          if (parameters != null && parameters.Length > 0)          {            if (sql.StartsWith("exec ", StringComparison.OrdinalIgnoreCase))              sb.AppendFormat(" {0}", string.Join(",", parameters.Select(o => o.ParameterName).ToArray()));            foreach (var item in parameters)            {              cmd.Parameters.Add(item);            }          }          cmd.Connection = conn;          cmd.CommandText = sb.ToString();          SqlDataAdapter adapter = new SqlDataAdapter(cmd);          DataTable table = new DataTable();          adapter.Fill(table);          conn.Close();//连接需要关闭          return table;        }        catch (Exception ex)        {          throw ex;        }        finally        {          if (conn.State == ConnectionState.Open)            conn.Close();        }      }      /// <summary>      /// 返回Datatable数据集      /// </summary>      /// <param name="proName">存储过程名</param>      /// <param name="parameters">参数列表</param>      /// <returns></returns>      [Obsolete("此方法已过时,请改用SqlQueryForDataTable")]      public System.Data.DataTable ExecuteForDataTable(string proName, IDataParameter[] parameters)      {        try        {          SqlConnection conn = new System.Data.SqlClient.SqlConnection();          conn.ConnectionString = Context.Database.Connection.ConnectionString;          if (conn.State != ConnectionState.Open)          {            conn.Open();          }          SqlCommand cmd = new SqlCommand(proName, conn);          cmd.CommandType = CommandType.StoredProcedure;          if (parameters != null && parameters.Length > 0)          {            foreach (var item in parameters)            {              cmd.Parameters.Add(item);            }          }          SqlDataAdapter adapter = new SqlDataAdapter(cmd);          DataTable table = new DataTable();          adapter.Fill(table);          return table;        }        catch (Exception ex)        {          throw ex;        }      }    }

这个实现类中定义了一个私有方法,指明了数据库访问的上下文DbContext

DbContext类如下:

public class DbContext : System.Data.Entity.DbContext    {       static DbContext()      {        //Database.SetInitializer(new CreateDatabaseIfNotExists<PersonalDbContext>());      }       public DbContext()        : base("Name=DbContext")      {      }      protected override void OnModelCreating(DbModelBuilder modelBuilder)      {        var typesToRegister = Assembly.GetExecutingAssembly().GetTypes()        .Where(type => !String.IsNullOrEmpty(type.Namespace))        .Where(type => type.BaseType != null && type.BaseType.IsGenericType &&          type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));        foreach (var type in typesToRegister)        {          dynamic configurationInstance = Activator.CreateInstance(type);          modelBuilder.Configurations.Add(configurationInstance);        }      }    }

我们将Name=DbContext 意思是去寻找webconfig中具有相同名称的值 ,所以,我们在配置文件中配置该项如下:

再configuration节点下面新建

<connectionStrings>    <add name="DbContext" providerName="System.Data.SqlClient" connectionString="Server=.;Database=Test;Uid=sa;Pwd=sa;"/>   </connectionStrings>

忘了说,这里对实现类中的一些扩展方法做了延伸,新建一个DynamicQueryable类,代码如下:

public static class DynamicQueryable    {      public static IQueryable<T> Where<T>(this IQueryable<T> source, string predicate, params object[] values)      {        return (IQueryable<T>)Where((IQueryable)source, predicate, values);      }      public static IQueryable Where(this IQueryable source, string predicate, params object[] values)      {        if (source == null) throw new ArgumentNullException("source");        if (predicate == null) throw new ArgumentNullException("predicate");        LambdaExpression lambda = DynamicExpression.ParseLambda(source.ElementType, typeof(bool), predicate, values);        return source.Provider.CreateQuery(          Expression.Call(            typeof(Queryable), "Where",            new Type[] { source.ElementType },            source.Expression, Expression.Quote(lambda)));      }      public static IQueryable Select(this IQueryable source, string selector, params object[] values)      {        if (source == null) throw new ArgumentNullException("source");        if (selector == null) throw new ArgumentNullException("selector");        LambdaExpression lambda = DynamicExpression.ParseLambda(source.ElementType, null, selector, values);        return source.Provider.CreateQuery(          Expression.Call(            typeof(Queryable), "Select",            new Type[] { source.ElementType, lambda.Body.Type },            source.Expression, Expression.Quote(lambda)));      }      public static IQueryable<dynamic> Select<T>(this IQueryable<T> source, string selector, params object[] values)      {        return (IQueryable<dynamic>)Select((IQueryable)source, selector, values);      }      public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string ordering, params object[] values)      {        return (IQueryable<T>)OrderBy((IQueryable)source, ordering, values);      }      public static IQueryable<T> ThenBy<T>(this IQueryable<T> source, string ordering, params object[] values)      {        return (IQueryable<T>)ThenBy((IQueryable)source, ordering, values);      }      public static IQueryable ThenBy(this IQueryable source, string ordering, params object[] values)      {        if (source == null) throw new ArgumentNullException("source");        if (ordering == null) throw new ArgumentNullException("ordering");        ParameterExpression[] parameters = new ParameterExpression[] {          Expression.Parameter(source.ElementType, "") };        ExpressionParser parser = new ExpressionParser(parameters, ordering, values);        IEnumerable<DynamicOrdering> orderings = parser.ParseOrdering();        Expression queryExpr = source.Expression;        string methodAsc = "ThenBy";        string methodDesc = "ThenByDescending";        foreach (DynamicOrdering o in orderings)        {          queryExpr = Expression.Call(            typeof(Queryable), o.Ascending ? methodAsc : methodDesc,            new Type[] { source.ElementType, o.Selector.Type },            queryExpr, Expression.Quote(Expression.Lambda(o.Selector, parameters)));        }        return source.Provider.CreateQuery(queryExpr);      }      public static IQueryable OrderBy(this IQueryable source, string ordering, params object[] values)      {        if (source == null) throw new ArgumentNullException("source");        if (ordering == null) throw new ArgumentNullException("ordering");        ParameterExpression[] parameters = new ParameterExpression[] {          Expression.Parameter(source.ElementType, "") };        ExpressionParser parser = new ExpressionParser(parameters, ordering, values);        IEnumerable<DynamicOrdering> orderings = parser.ParseOrdering();        Expression queryExpr = source.Expression;        string methodAsc = "OrderBy";        string methodDesc = "OrderByDescending";        foreach (DynamicOrdering o in orderings)        {          queryExpr = Expression.Call(            typeof(Queryable), o.Ascending ? methodAsc : methodDesc,            new Type[] { source.ElementType, o.Selector.Type },            queryExpr, Expression.Quote(Expression.Lambda(o.Selector, parameters)));          methodAsc = "ThenBy";          methodDesc = "ThenByDescending";        }        return source.Provider.CreateQuery(queryExpr);      }      public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string propertyName, bool ascending)        where T : class      {        Type type = typeof(T);        PropertyInfo property = type.GetProperty(propertyName);        if (property == null)          throw new ArgumentException("propertyName", "Not Exist");        ParameterExpression param = Expression.Parameter(type, "p");        Expression propertyAccessExpression = Expression.MakeMemberAccess(param, property);        LambdaExpression orderByExpression = Expression.Lambda(propertyAccessExpression, param);        string methodName = ascending ? "OrderBy" : "OrderByDescending";        MethodCallExpression resultExp = Expression.Call(typeof(Queryable), methodName,          new Type[] { type, property.PropertyType }, source.Expression, Expression.Quote(orderByExpression));        return source.Provider.CreateQuery<T>(resultExp);      }      public static IQueryable Take(this IQueryable source, int count)      {        if (source == null) throw new ArgumentNullException("source");        return source.Provider.CreateQuery(          Expression.Call(            typeof(Queryable), "Take",            new Type[] { source.ElementType },            source.Expression, Expression.Constant(count)));      }      public static IQueryable Skip(this IQueryable source, int count)      {        if (source == null) throw new ArgumentNullException("source");        return source.Provider.CreateQuery(          Expression.Call(            typeof(Queryable), "Skip",            new Type[] { source.ElementType },            source.Expression, Expression.Constant(count)));      }      public static IQueryable GroupBy(this IQueryable source, string keySelector, string elementSelector, params object[] values)      {        if (source == null) throw new ArgumentNullException("source");        if (keySelector == null) throw new ArgumentNullException("keySelector");        if (elementSelector == null) throw new ArgumentNullException("elementSelector");        LambdaExpression keyLambda = DynamicExpression.ParseLambda(source.ElementType, null, keySelector, values);        LambdaExpression elementLambda = DynamicExpression.ParseLambda(source.ElementType, null, elementSelector, values);        return source.Provider.CreateQuery(          Expression.Call(            typeof(Queryable), "GroupBy",            new Type[] { source.ElementType, keyLambda.Body.Type, elementLambda.Body.Type },            source.Expression, Expression.Quote(keyLambda), Expression.Quote(elementLambda)));      }      public static bool Any(this IQueryable source)      {        if (source == null) throw new ArgumentNullException("source");        return (bool)source.Provider.Execute(          Expression.Call(            typeof(Queryable), "Any",            new Type[] { source.ElementType }, source.Expression));      }      public static int Count(this IQueryable source)      {        if (source == null) throw new ArgumentNullException("source");        return (int)source.Provider.Execute(          Expression.Call(            typeof(Queryable), "Count",            new Type[] { source.ElementType }, source.Expression));      }    }    public abstract class DynamicClass    {      public override string ToString()      {        PropertyInfo[] props = this.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);        StringBuilder sb = new StringBuilder();        sb.Append("{");        for (int i = 0; i < props.Length; i++)        {          if (i > 0) sb.Append(", ");          sb.Append(props[i].Name);          sb.Append("=");          sb.Append(props[i].GetValue(this, null));        }        sb.Append("}");        return sb.ToString();      }    }    public class DynamicProperty    {      string name;      Type type;      public DynamicProperty(string name, Type type)      {        if (name == null) throw new ArgumentNullException("name");        if (type == null) throw new ArgumentNullException("type");        this.name = name;        this.type = type;      }      public string Name      {        get { return name; }      }      public Type Type      {        get { return type; }      }    }    public static class DynamicExpression    {      public static Expression Parse(Type resultType, string expression, params object[] values)      {        ExpressionParser parser = new ExpressionParser(null, expression, values);        return parser.Parse(resultType);      }      public static LambdaExpression ParseLambda(Type itType, Type resultType, string expression, params object[] values)      {        return ParseLambda(new ParameterExpression[] { Expression.Parameter(itType, "") }, resultType, expression, values);      }      public static LambdaExpression ParseLambda(ParameterExpression[] parameters, Type resultType, string expression, params object[] values)      {        ExpressionParser parser = new ExpressionParser(parameters, expression, values);        return Expression.Lambda(parser.Parse(resultType), parameters);      }      public static Expression<Func<T, S>> ParseLambda<T, S>(string expression, params object[] values)      {        return (Expression<Func<T, S>>)ParseLambda(typeof(T), typeof(S), expression, values);      }      public static Type CreateClass(params DynamicProperty[] properties)      {        return ClassFactory.Instance.GetDynamicClass(properties);      }      public static Type CreateClass(IEnumerable<DynamicProperty> properties)      {        return ClassFactory.Instance.GetDynamicClass(properties);      }    }    internal class DynamicOrdering    {      public Expression Selector;      public bool Ascending;    }    internal class Signature : IEquatable<Signature>    {      public DynamicProperty[] properties;      public int hashCode;      public Signature(IEnumerable<DynamicProperty> properties)      {        this.properties = properties.ToArray();        hashCode = 0;        foreach (DynamicProperty p in properties)        {          hashCode ^= p.Name.GetHashCode() ^ p.Type.GetHashCode();        }      }      public override int GetHashCode()      {        return hashCode;      }      public override bool Equals(object obj)      {        return obj is Signature ? Equals((Signature)obj) : false;      }      public bool Equals(Signature other)      {        if (properties.Length != other.properties.Length) return false;        for (int i = 0; i < properties.Length; i++)        {          if (properties[i].Name != other.properties[i].Name ||            properties[i].Type != other.properties[i].Type) return false;        }        return true;      }    }    internal class ClassFactory    {      public static readonly ClassFactory Instance = new ClassFactory();      static ClassFactory() { } // Trigger lazy initialization of static fields      ModuleBuilder module;      Dictionary<Signature, Type> classes;      int classCount;      ReaderWriterLock rwLock;      private ClassFactory()      {        AssemblyName name = new AssemblyName("DynamicClasses");        AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);  #if ENABLE_LINQ_PARTIAL_TRUST        new ReflectionPermission(PermissionState.Unrestricted).Assert();  #endif        try        {          module = assembly.DefineDynamicModule("Module");        }        finally        {  #if ENABLE_LINQ_PARTIAL_TRUST          PermissionSet.RevertAssert();  #endif        }        classes = new Dictionary<Signature, Type>();        rwLock = new ReaderWriterLock();      }      public Type GetDynamicClass(IEnumerable<DynamicProperty> properties)      {        rwLock.AcquireReaderLock(Timeout.Infinite);        try        {          Signature signature = new Signature(properties);          Type type;          if (!classes.TryGetValue(signature, out type))          {            type = CreateDynamicClass(signature.properties);            classes.Add(signature, type);          }          return type;        }        finally        {          rwLock.ReleaseReaderLock();        }      }      Type CreateDynamicClass(DynamicProperty[] properties)      {        LockCookie cookie = rwLock.UpgradeToWriterLock(Timeout.Infinite);        try        {          string typeName = "DynamicClass" + (classCount + 1);  #if ENABLE_LINQ_PARTIAL_TRUST          new ReflectionPermission(PermissionState.Unrestricted).Assert();  #endif          try          {            TypeBuilder tb = this.module.DefineType(typeName, TypeAttributes.Class |              TypeAttributes.Public, typeof(DynamicClass));            FieldInfo[] fields = GenerateProperties(tb, properties);            GenerateEquals(tb, fields);            GenerateGetHashCode(tb, fields);            Type result = tb.CreateType();            classCount++;            return result;          }          finally          {  #if ENABLE_LINQ_PARTIAL_TRUST            PermissionSet.RevertAssert();  #endif          }        }        finally        {          rwLock.DowngradeFromWriterLock(ref cookie);        }      }      FieldInfo[] GenerateProperties(TypeBuilder tb, DynamicProperty[] properties)      {        FieldInfo[] fields = new FieldBuilder[properties.Length];        for (int i = 0; i < properties.Length; i++)        {          DynamicProperty dp = properties[i];          FieldBuilder fb = tb.DefineField("_" + dp.Name, dp.Type, FieldAttributes.Private);          PropertyBuilder pb = tb.DefineProperty(dp.Name, PropertyAttributes.HasDefault, dp.Type, null);          MethodBuilder mbGet = tb.DefineMethod("get_" + dp.Name,            MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig,            dp.Type, Type.EmptyTypes);          ILGenerator genGet = mbGet.GetILGenerator();          genGet.Emit(OpCodes.Ldarg_0);          genGet.Emit(OpCodes.Ldfld, fb);          genGet.Emit(OpCodes.Ret);          MethodBuilder mbSet = tb.DefineMethod("set_" + dp.Name,            MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig,            null, new Type[] { dp.Type });          ILGenerator genSet = mbSet.GetILGenerator();          genSet.Emit(OpCodes.Ldarg_0);          genSet.Emit(OpCodes.Ldarg_1);          genSet.Emit(OpCodes.Stfld, fb);          genSet.Emit(OpCodes.Ret);          pb.SetGetMethod(mbGet);          pb.SetSetMethod(mbSet);          fields[i] = fb;        }        return fields;      }      void GenerateEquals(TypeBuilder tb, FieldInfo[] fields)      {        MethodBuilder mb = tb.DefineMethod("Equals",          MethodAttributes.Public | MethodAttributes.ReuseSlot |          MethodAttributes.Virtual | MethodAttributes.HideBySig,          typeof(bool), new Type[] { typeof(object) });        ILGenerator gen = mb.GetILGenerator();        LocalBuilder other = gen.DeclareLocal(tb);        Label next = gen.DefineLabel();        gen.Emit(OpCodes.Ldarg_1);        gen.Emit(OpCodes.Isinst, tb);        gen.Emit(OpCodes.Stloc, other);        gen.Emit(OpCodes.Ldloc, other);        gen.Emit(OpCodes.Brtrue_S, next);        gen.Emit(OpCodes.Ldc_I4_0);        gen.Emit(OpCodes.Ret);        gen.MarkLabel(next);        foreach (FieldInfo field in fields)        {          Type ft = field.FieldType;          Type ct = typeof(EqualityComparer<>).MakeGenericType(ft);          next = gen.DefineLabel();          gen.EmitCall(OpCodes.Call, ct.GetMethod("get_Default"), null);          gen.Emit(OpCodes.Ldarg_0);          gen.Emit(OpCodes.Ldfld, field);          gen.Emit(OpCodes.Ldloc, other);          gen.Emit(OpCodes.Ldfld, field);          gen.EmitCall(OpCodes.Callvirt, ct.GetMethod("Equals", new Type[] { ft, ft }), null);          gen.Emit(OpCodes.Brtrue_S, next);          gen.Emit(OpCodes.Ldc_I4_0);          gen.Emit(OpCodes.Ret);          gen.MarkLabel(next);        }        gen.Emit(OpCodes.Ldc_I4_1);        gen.Emit(OpCodes.Ret);      }      void GenerateGetHashCode(TypeBuilder tb, FieldInfo[] fields)      {        MethodBuilder mb = tb.DefineMethod("GetHashCode",          MethodAttributes.Public | MethodAttributes.ReuseSlot |          MethodAttributes.Virtual | MethodAttributes.HideBySig,          typeof(int), Type.EmptyTypes);        ILGenerator gen = mb.GetILGenerator();        gen.Emit(OpCodes.Ldc_I4_0);        foreach (FieldInfo field in fields)        {          Type ft = field.FieldType;          Type ct = typeof(EqualityComparer<>).MakeGenericType(ft);          gen.EmitCall(OpCodes.Call, ct.GetMethod("get_Default"), null);          gen.Emit(OpCodes.Ldarg_0);          gen.Emit(OpCodes.Ldfld, field);          gen.EmitCall(OpCodes.Callvirt, ct.GetMethod("GetHashCode", new Type[] { ft }), null);          gen.Emit(OpCodes.Xor);        }        gen.Emit(OpCodes.Ret);      }    }    public sealed class ParseException : Exception    {      int position;      public ParseException(string message, int position)        : base(message)      {        this.position = position;      }      public int Position      {        get { return position; }      }      public override string ToString()      {        return string.Format(Res.ParseExceptionFormat, Message, position);      }    }    internal class ExpressionParser    {      struct Token      {        public TokenId id;        public string text;        public int pos;      }      enum TokenId      {        Unknown,        End,        Identifier,        StringLiteral,        IntegerLiteral,        RealLiteral,        Exclamation,        Percent,        Amphersand,        OpenParen,        CloseParen,        Asterisk,        Plus,        Comma,        Minus,        Dot,        Slash,        Colon,        LessThan,        Equal,        GreaterThan,        Question,        OpenBracket,        CloseBracket,        Bar,        ExclamationEqual,        DoubleAmphersand,        LessThanEqual,        LessGreater,        DoubleEqual,        GreaterThanEqual,        DoubleBar      }      interface ILogicalSignatures      {        void F(bool x, bool y);        void F(bool? x, bool? y);      }      interface IArithmeticSignatures      {        void F(int x, int y);        void F(uint x, uint y);        void F(long x, long y);        void F(ulong x, ulong y);        void F(float x, float y);        void F(double x, double y);        void F(decimal x, decimal y);        void F(int? x, int? y);        void F(uint? x, uint? y);        void F(long? x, long? y);        void F(ulong? x, ulong? y);        void F(float? x, float? y);        void F(double? x, double? y);        void F(decimal? x, decimal? y);      }      interface IRelationalSignatures : IArithmeticSignatures      {        void F(string x, string y);        void F(char x, char y);        void F(DateTime x, DateTime y);        void F(TimeSpan x, TimeSpan y);        void F(char? x, char? y);        void F(DateTime? x, DateTime? y);        void F(TimeSpan? x, TimeSpan? y);      }      interface IEqualitySignatures : IRelationalSignatures      {        void F(bool x, bool y);        void F(bool? x, bool? y);      }      interface IAddSignatures : IArithmeticSignatures      {        void F(DateTime x, TimeSpan y);        void F(TimeSpan x, TimeSpan y);        void F(DateTime? x, TimeSpan? y);        void F(TimeSpan? x, TimeSpan? y);      }      interface ISubtractSignatures : IAddSignatures      {        void F(DateTime x, DateTime y);        void F(DateTime? x, DateTime? y);      }      interface INegationSignatures      {        void F(int x);        void F(long x);        void F(float x);        void F(double x);        void F(decimal x);        void F(int? x);        void F(long? x);        void F(float? x);        void F(double? x);        void F(decimal? x);      }      interface INotSignatures      {        void F(bool x);        void F(bool? x);      }      interface IEnumerableSignatures      {        void Where(bool predicate);        void Any();        void Any(bool predicate);        void All(bool predicate);        void Count();        void Count(bool predicate);        void Min(object selector);        void Max(object selector);        void Sum(int selector);        void Sum(int? selector);        void Sum(long selector);        void Sum(long? selector);        void Sum(float selector);        void Sum(float? selector);        void Sum(double selector);        void Sum(double? selector);        void Sum(decimal selector);        void Sum(decimal? selector);        void Average(int selector);        void Average(int? selector);        void Average(long selector);        void Average(long? selector);        void Average(float selector);        void Average(float? selector);        void Average(double selector);        void Average(double? selector);        void Average(decimal selector);        void Average(decimal? selector);      }      static readonly Type[] predefinedTypes = {        typeof(Object),        typeof(Boolean),        typeof(Char),        typeof(String),        typeof(SByte),        typeof(Byte),        typeof(Int16),        typeof(UInt16),        typeof(Int32),        typeof(UInt32),        typeof(Int64),        typeof(UInt64),        typeof(Single),        typeof(Double),        typeof(Decimal),        typeof(DateTime),        typeof(TimeSpan),        typeof(Guid),        typeof(Math),        typeof(Convert)      };      static readonly Expression trueLiteral = Expression.Constant(true);      static readonly Expression falseLiteral = Expression.Constant(false);      static readonly Expression nullLiteral = Expression.Constant(null);      static readonly string keywordIt = "it";      static readonly string keywordIif = "iif";      static readonly string keywordNew = "new";      static Dictionary<string, object> keywords;      Dictionary<string, object> symbols;      IDictionary<string, object> externals;      Dictionary<Expression, string> literals;      ParameterExpression it;      string text;      int textPos;      int textLen;      char ch;      Token token;      public ExpressionParser(ParameterExpression[] parameters, string expression, object[] values)      {        if (expression == null) throw new ArgumentNullException("expression");        if (keywords == null) keywords = CreateKeywords();        symbols = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);        literals = new Dictionary<Expression, string>();        if (parameters != null) ProcessParameters(parameters);        if (values != null) ProcessValues(values);        text = expression;        textLen = text.Length;        SetTextPos(0);        NextToken();      }      void ProcessParameters(ParameterExpression[] parameters)      {        foreach (ParameterExpression pe in parameters)          if (!String.IsNullOrEmpty(pe.Name))            AddSymbol(pe.Name, pe);        if (parameters.Length == 1 && String.IsNullOrEmpty(parameters[0].Name))          it = parameters[0];      }      void ProcessValues(object[] values)      {        for (int i = 0; i < values.Length; i++)        {          object value = values[i];          if (i == values.Length - 1 && value is IDictionary<string, object>)          {            externals = (IDictionary<string, object>)value;          }          else          {            AddSymbol("@" + i.ToString(System.Globalization.CultureInfo.InvariantCulture), value);          }        }      }      void AddSymbol(string name, object value)      {        if (symbols.ContainsKey(name))          throw ParseError(Res.DuplicateIdentifier, name);        symbols.Add(name, value);      }      public Expression Parse(Type resultType)      {        int exprPos = token.pos;        Expression expr = ParseExpression();        if (resultType != null)          if ((expr = PromoteExpression(expr, resultType, true)) == null)            throw ParseError(exprPos, Res.ExpressionTypeMismatch, GetTypeName(resultType));        ValidateToken(TokenId.End, Res.SyntaxError);        return expr;      }  #pragma warning disable 0219      public IEnumerable<DynamicOrdering> ParseOrdering()      {        List<DynamicOrdering> orderings = new List<DynamicOrdering>();        while (true)        {          Expression expr = ParseExpression();          bool ascending = true;          if (TokenIdentifierIs("asc") || TokenIdentifierIs("ascending"))          {            NextToken();          }          else if (TokenIdentifierIs("desc") || TokenIdentifierIs("descending"))          {            NextToken();            ascending = false;          }          orderings.Add(new DynamicOrdering { Selector = expr, Ascending = ascending });          if (token.id != TokenId.Comma) break;          NextToken();        }        ValidateToken(TokenId.End, Res.SyntaxError);        return orderings;      }  #pragma warning restore 0219      // ?: operator      Expression ParseExpression()      {        int errorPos = token.pos;        Expression expr = ParseLogicalOr();        if (token.id == TokenId.Question)        {          NextToken();          Expression expr1 = ParseExpression();          ValidateToken(TokenId.Colon, Res.ColonExpected);          NextToken();          Expression expr2 = ParseExpression();          expr = GenerateConditional(expr, expr1, expr2, errorPos);        }        return expr;      }      // ||, or operator      Expression ParseLogicalOr()      {        Expression left = ParseLogicalAnd();        while (token.id == TokenId.DoubleBar || TokenIdentifierIs("or"))        {          Token op = token;          NextToken();          Expression right = ParseLogicalAnd();          CheckAndPromoteOperands(typeof(ILogicalSignatures), op.text, ref left, ref right, op.pos);          left = Expression.OrElse(left, right);        }        return left;      }      // &&, and operator      Expression ParseLogicalAnd()      {        Expression left = ParseComparison();        while (token.id == TokenId.DoubleAmphersand || TokenIdentifierIs("and"))        {          Token op = token;          NextToken();          Expression right = ParseComparison();          CheckAndPromoteOperands(typeof(ILogicalSignatures), op.text, ref left, ref right, op.pos);          left = Expression.AndAlso(left, right);        }        return left;      }      // =, ==, !=, <>, >, >=, <, <= operators      Expression ParseComparison()      {        Expression left = ParseAdditive();        while (token.id == TokenId.Equal || token.id == TokenId.DoubleEqual ||          token.id == TokenId.ExclamationEqual || token.id == TokenId.LessGreater ||          token.id == TokenId.GreaterThan || token.id == TokenId.GreaterThanEqual ||          token.id == TokenId.LessThan || token.id == TokenId.LessThanEqual)        {          Token op = token;          NextToken();          Expression right = ParseAdditive();          bool isEquality = op.id == TokenId.Equal || op.id == TokenId.DoubleEqual ||            op.id == TokenId.ExclamationEqual || op.id == TokenId.LessGreater;          if (isEquality && !left.Type.IsValueType && !right.Type.IsValueType)          {            if (left.Type != right.Type)            {              if (left.Type.IsAssignableFrom(right.Type))              {                right = Expression.Convert(right, left.Type);              }              else if (right.Type.IsAssignableFrom(left.Type))              {                left = Expression.Convert(left, right.Type);              }              else              {                throw IncompatibleOperandsError(op.text, left, right, op.pos);              }            }          }          else if (IsEnumType(left.Type) || IsEnumType(right.Type))          {            if (left.Type != right.Type)            {              Expression e;              if ((e = PromoteExpression(right, left.Type, true)) != null)              {                right = e;              }              else if ((e = PromoteExpression(left, right.Type, true)) != null)              {                left = e;              }              else              {                throw IncompatibleOperandsError(op.text, left, right, op.pos);              }            }          }          else          {            CheckAndPromoteOperands(isEquality ? typeof(IEqualitySignatures) : typeof(IRelationalSignatures),              op.text, ref left, ref right, op.pos);          }          switch (op.id)          {            case TokenId.Equal:            case TokenId.DoubleEqual:              left = GenerateEqual(left, right);              break;            case TokenId.ExclamationEqual:            case TokenId.LessGreater:              left = GenerateNotEqual(left, right);              break;            case TokenId.GreaterThan:              left = GenerateGreaterThan(left, right);              break;            case TokenId.GreaterThanEqual:              left = GenerateGreaterThanEqual(left, right);              break;            case TokenId.LessThan:              left = GenerateLessThan(left, right);              break;            case TokenId.LessThanEqual:              left = GenerateLessThanEqual(left, right);              break;          }        }        return left;      }      // +, -, & operators      Expression ParseAdditive()      {        Expression left = ParseMultiplicative();        while (token.id == TokenId.Plus || token.id == TokenId.Minus ||          token.id == TokenId.Amphersand)        {          Token op = token;          NextToken();          Expression right = ParseMultiplicative();          switch (op.id)          {            case TokenId.Plus:              if (left.Type == typeof(string) || right.Type == typeof(string))                goto case TokenId.Amphersand;              CheckAndPromoteOperands(typeof(IAddSignatures), op.text, ref left, ref right, op.pos);              left = GenerateAdd(left, right);              break;            case TokenId.Minus:              CheckAndPromoteOperands(typeof(ISubtractSignatures), op.text, ref left, ref right, op.pos);              left = GenerateSubtract(left, right);              break;            case TokenId.Amphersand:              left = GenerateStringConcat(left, right);              break;          }        }        return left;      }      // *, /, %, mod operators      Expression ParseMultiplicative()      {        Expression left = ParseUnary();        while (token.id == TokenId.Asterisk || token.id == TokenId.Slash ||          token.id == TokenId.Percent || TokenIdentifierIs("mod"))        {          Token op = token;          NextToken();          Expression right = ParseUnary();          CheckAndPromoteOperands(typeof(IArithmeticSignatures), op.text, ref left, ref right, op.pos);          switch (op.id)          {            case TokenId.Asterisk:              left = Expression.Multiply(left, right);              break;            case TokenId.Slash:              left = Expression.pide(left, right);              break;            case TokenId.Percent:            case TokenId.Identifier:              left = Expression.Modulo(left, right);              break;          }        }        return left;      }      // -, !, not unary operators      Expression ParseUnary()      {        if (token.id == TokenId.Minus || token.id == TokenId.Exclamation ||          TokenIdentifierIs("not"))        {          Token op = token;          NextToken();          if (op.id == TokenId.Minus && (token.id == TokenId.IntegerLiteral ||            token.id == TokenId.RealLiteral))          {            token.text = "-" + token.text;            token.pos = op.pos;            return ParsePrimary();          }          Expression expr = ParseUnary();          if (op.id == TokenId.Minus)          {            CheckAndPromoteOperand(typeof(INegationSignatures), op.text, ref expr, op.pos);            expr = Expression.Negate(expr);          }          else          {            CheckAndPromoteOperand(typeof(INotSignatures), op.text, ref expr, op.pos);            expr = Expression.Not(expr);          }          return expr;        }        return ParsePrimary();      }      Expression ParsePrimary()      {        Expression expr = ParsePrimaryStart();        while (true)        {          if (token.id == TokenId.Dot)          {            NextToken();            expr = ParseMemberAccess(null, expr);          }          else if (token.id == TokenId.OpenBracket)          {            expr = ParseElementAccess(expr);          }          else          {            break;          }        }        return expr;      }      Expression ParsePrimaryStart()      {        switch (token.id)        {          case TokenId.Identifier:            return ParseIdentifier();          case TokenId.StringLiteral:            return ParseStringLiteral();          case TokenId.IntegerLiteral:            return ParseIntegerLiteral();          case TokenId.RealLiteral:            return ParseRealLiteral();          case TokenId.OpenParen:            return ParseParenExpression();          default:            throw ParseError(Res.ExpressionExpected);        }      }      Expression ParseStringLiteral()      {        ValidateToken(TokenId.StringLiteral);        char quote = token.text[0];        string s = token.text.Substring(1, token.text.Length - 2);        int start = 0;        while (true)        {          int i = s.IndexOf(quote, start);          if (i < 0) break;          s = s.Remove(i, 1);          start = i + 1;        }        //if (quote == '\'') {        //  if (s.Length != 1)        //    throw ParseError(Res.InvalidCharacterLiteral);        //  NextToken();        //  return CreateLiteral(s[0], s);        //}        NextToken();        return CreateLiteral(s, s);      }      Expression ParseIntegerLiteral()      {        ValidateToken(TokenId.IntegerLiteral);        string text = token.text;        if (text[0] != '-')        {          ulong value;          if (!UInt64.TryParse(text, out value))            throw ParseError(Res.InvalidIntegerLiteral, text);          NextToken();          if (value <= (ulong)Int32.MaxValue) return CreateLiteral((int)value, text);          if (value <= (ulong)UInt32.MaxValue) return CreateLiteral((uint)value, text);          if (value <= (ulong)Int64.MaxValue) return CreateLiteral((long)value, text);          return CreateLiteral(value, text);        }        else        {          long value;          if (!Int64.TryParse(text, out value))            throw ParseError(Res.InvalidIntegerLiteral, text);          NextToken();          if (value >= Int32.MinValue && value <= Int32.MaxValue)            return CreateLiteral((int)value, text);          return CreateLiteral(value, text);        }      }      Expression ParseRealLiteral()      {        ValidateToken(TokenId.RealLiteral);        string text = token.text;        object value = null;        char last = text[text.Length - 1];        if (last == 'F' || last == 'f')        {          float f;          if (Single.TryParse(text.Substring(0, text.Length - 1), out f)) value = f;        }        else        {          double d;          if (Double.TryParse(text, out d)) value = d;        }        if (value == null) throw ParseError(Res.InvalidRealLiteral, text);        NextToken();        return CreateLiteral(value, text);      }      Expression CreateLiteral(object value, string text)      {        ConstantExpression expr = Expression.Constant(value);        literals.Add(expr, text);        return expr;      }      Expression ParseParenExpression()      {        ValidateToken(TokenId.OpenParen, Res.OpenParenExpected);        NextToken();        Expression e = ParseExpression();        ValidateToken(TokenId.CloseParen, Res.CloseParenOrOperatorExpected);        NextToken();        return e;      }      Expression ParseIdentifier()      {        ValidateToken(TokenId.Identifier);        object value;        if (keywords.TryGetValue(token.text, out value))        {          if (value is Type) return ParseTypeAccess((Type)value);          if (value == (object)keywordIt) return ParseIt();          if (value == (object)keywordIif) return ParseIif();          if (value == (object)keywordNew) return ParseNew();          NextToken();          return (Expression)value;        }        if (symbols.TryGetValue(token.text, out value) ||          externals != null && externals.TryGetValue(token.text, out value))        {          Expression expr = value as Expression;          if (expr == null)          {            expr = Expression.Constant(value);          }          else          {            LambdaExpression lambda = expr as LambdaExpression;            if (lambda != null) return ParseLambdaInvocation(lambda);          }          NextToken();          return expr;        }        if (it != null) return ParseMemberAccess(null, it);        throw ParseError(Res.UnknownIdentifier, token.text);      }      Expression ParseIt()      {        if (it == null)          throw ParseError(Res.NoItInScope);        NextToken();        return it;      }      Expression ParseIif()      {        int errorPos = token.pos;        NextToken();        Expression[] args = ParseArgumentList();        if (args.Length != 3)          throw ParseError(errorPos, Res.IifRequiresThreeArgs);        return GenerateConditional(args[0], args[1], args[2], errorPos);      }      Expression GenerateConditional(Expression test, Expression expr1, Expression expr2, int errorPos)      {        if (test.Type != typeof(bool))          throw ParseError(errorPos, Res.FirstExprMustBeBool);        if (expr1.Type != expr2.Type)        {          Expression expr1as2 = expr2 != nullLiteral ? PromoteExpression(expr1, expr2.Type, true) : null;          Expression expr2as1 = expr1 != nullLiteral ? PromoteExpression(expr2, expr1.Type, true) : null;          if (expr1as2 != null && expr2as1 == null)          {            expr1 = expr1as2;          }          else if (expr2as1 != null && expr1as2 == null)          {            expr2 = expr2as1;          }          else          {            string type1 = expr1 != nullLiteral ? expr1.Type.Name : "null";            string type2 = expr2 != nullLiteral ? expr2.Type.Name : "null";            if (expr1as2 != null && expr2as1 != null)              throw ParseError(errorPos, Res.BothTypesConvertToOther, type1, type2);            throw ParseError(errorPos, Res.NeitherTypeConvertsToOther, type1, type2);          }        }        return Expression.Condition(test, expr1, expr2);      }      Expression ParseNew()      {        NextToken();        ValidateToken(TokenId.OpenParen, Res.OpenParenExpected);        NextToken();        List<DynamicProperty> properties = new List<DynamicProperty>();        List<Expression> expressions = new List<Expression>();        while (true)        {          int exprPos = token.pos;          Expression expr = ParseExpression();          string propName;          if (TokenIdentifierIs("as"))          {            NextToken();            propName = GetIdentifier();            NextToken();          }          else          {            MemberExpression me = expr as MemberExpression;            if (me == null) throw ParseError(exprPos, Res.MissingAsClause);            propName = me.Member.Name;          }          expressions.Add(expr);          properties.Add(new DynamicProperty(propName, expr.Type));          if (token.id != TokenId.Comma) break;          NextToken();        }        ValidateToken(TokenId.CloseParen, Res.CloseParenOrCommaExpected);        NextToken();        Type type = DynamicExpression.CreateClass(properties);        MemberBinding[] bindings = new MemberBinding[properties.Count];        for (int i = 0; i < bindings.Length; i++)          bindings[i] = Expression.Bind(type.GetProperty(properties[i].Name), expressions[i]);        return Expression.MemberInit(Expression.New(type), bindings);      }      Expression ParseLambdaInvocation(LambdaExpression lambda)      {        int errorPos = token.pos;        NextToken();        Expression[] args = ParseArgumentList();        MethodBase method;        if (FindMethod(lambda.Type, "Invoke", false, args, out method) != 1)          throw ParseError(errorPos, Res.ArgsIncompatibleWithLambda);        return Expression.Invoke(lambda, args);      }      Expression ParseTypeAccess(Type type)      {        int errorPos = token.pos;        NextToken();        if (token.id == TokenId.Question)        {          if (!type.IsValueType || IsNullableType(type))            throw ParseError(errorPos, Res.TypeHasNoNullableForm, GetTypeName(type));          type = typeof(Nullable<>).MakeGenericType(type);          NextToken();        }        if (token.id == TokenId.OpenParen)        {          Expression[] args = ParseArgumentList();          MethodBase method;          switch (FindBestMethod(type.GetConstructors(), args, out method))          {            case 0:              if (args.Length == 1)                return GenerateConversion(args[0], type, errorPos);              throw ParseError(errorPos, Res.NoMatchingConstructor, GetTypeName(type));            case 1:              return Expression.New((ConstructorInfo)method, args);            default:              throw ParseError(errorPos, Res.AmbiguousConstructorInvocation, GetTypeName(type));          }        }        ValidateToken(TokenId.Dot, Res.DotOrOpenParenExpected);        NextToken();        return ParseMemberAccess(type, null);      }      Expression GenerateConversion(Expression expr, Type type, int errorPos)      {        Type exprType = expr.Type;        if (exprType == type) return expr;        if (exprType.IsValueType && type.IsValueType)        {          if ((IsNullableType(exprType) || IsNullableType(type)) &&            GetNonNullableType(exprType) == GetNonNullableType(type))            return Expression.Convert(expr, type);          if ((IsNumericType(exprType) || IsEnumType(exprType)) &&            (IsNumericType(type)) || IsEnumType(type))            return Expression.ConvertChecked(expr, type);        }        if (exprType.IsAssignableFrom(type) || type.IsAssignableFrom(exprType) ||          exprType.IsInterface || type.IsInterface)          return Expression.Convert(expr, type);        throw ParseError(errorPos, Res.CannotConvertValue,          GetTypeName(exprType), GetTypeName(type));      }      Expression ParseMemberAccess(Type type, Expression instance)      {        if (instance != null) type = instance.Type;        int errorPos = token.pos;        string id = GetIdentifier();        NextToken();        if (token.id == TokenId.OpenParen)        {          if (instance != null && type != typeof(string))          {            Type enumerableType = FindGenericType(typeof(IEnumerable<>), type);            if (enumerableType != null)            {              Type elementType = enumerableType.GetGenericArguments()[0];              return ParseAggregate(instance, elementType, id, errorPos);            }          }          Expression[] args = ParseArgumentList();          MethodBase mb;          switch (FindMethod(type, id, instance == null, args, out mb))          {            case 0:              throw ParseError(errorPos, Res.NoApplicableMethod,                id, GetTypeName(type));            case 1:              MethodInfo method = (MethodInfo)mb;              if (!IsPredefinedType(method.DeclaringType))                throw ParseError(errorPos, Res.MethodsAreInaccessible, GetTypeName(method.DeclaringType));              if (method.ReturnType == typeof(void))                throw ParseError(errorPos, Res.MethodIsVoid,                  id, GetTypeName(method.DeclaringType));              return Expression.Call(instance, (MethodInfo)method, args);            default:              throw ParseError(errorPos, Res.AmbiguousMethodInvocation,                id, GetTypeName(type));          }        }        else        {          MemberInfo member = FindPropertyOrField(type, id, instance == null);          if (member == null)            throw ParseError(errorPos, Res.UnknownPropertyOrField,              id, GetTypeName(type));          return member is PropertyInfo ?            Expression.Property(instance, (PropertyInfo)member) :            Expression.Field(instance, (FieldInfo)member);        }      }      static Type FindGenericType(Type generic, Type type)      {        while (type != null && type != typeof(object))        {          if (type.IsGenericType && type.GetGenericTypeDefinition() == generic) return type;          if (generic.IsInterface)          {            foreach (Type intfType in type.GetInterfaces())            {              Type found = FindGenericType(generic, intfType);              if (found != null) return found;            }          }          type = type.BaseType;        }        return null;      }      Expression ParseAggregate(Expression instance, Type elementType, string methodName, int errorPos)      {        ParameterExpression outerIt = it;        ParameterExpression innerIt = Expression.Parameter(elementType, "");        it = innerIt;        Expression[] args = ParseArgumentList();        it = outerIt;        MethodBase signature;        if (FindMethod(typeof(IEnumerableSignatures), methodName, false, args, out signature) != 1)          throw ParseError(errorPos, Res.NoApplicableAggregate, methodName);        Type[] typeArgs;        if (signature.Name == "Min" || signature.Name == "Max")        {          typeArgs = new Type[] { elementType, args[0].Type };        }        else        {          typeArgs = new Type[] { elementType };        }        if (args.Length == 0)        {          args = new Expression[] { instance };        }        else        {          args = new Expression[] { instance, Expression.Lambda(args[0], innerIt) };        }        return Expression.Call(typeof(Enumerable), signature.Name, typeArgs, args);      }      Expression[] ParseArgumentList()      {        ValidateToken(TokenId.OpenParen, Res.OpenParenExpected);        NextToken();        Expression[] args = token.id != TokenId.CloseParen ? ParseArguments() : new Expression[0];        ValidateToken(TokenId.CloseParen, Res.CloseParenOrCommaExpected);        NextToken();        return args;      }      Expression[] ParseArguments()      {        List<Expression> argList = new List<Expression>();        while (true)        {          argList.Add(ParseExpression());          if (token.id != TokenId.Comma) break;          NextToken();        }        return argList.ToArray();      }      Expression ParseElementAccess(Expression expr)      {        int errorPos = token.pos;        ValidateToken(TokenId.OpenBracket, Res.OpenParenExpected);        NextToken();        Expression[] args = ParseArguments();        ValidateToken(TokenId.CloseBracket, Res.CloseBracketOrCommaExpected);        NextToken();        if (expr.Type.IsArray)        {          if (expr.Type.GetArrayRank() != 1 || args.Length != 1)            throw ParseError(errorPos, Res.CannotIndexMultiDimArray);          Expression index = PromoteExpression(args[0], typeof(int), true);          if (index == null)            throw ParseError(errorPos, Res.InvalidIndex);          return Expression.ArrayIndex(expr, index);        }        else        {          MethodBase mb;          switch (FindIndexer(expr.Type, args, out mb))          {            case 0:              throw ParseError(errorPos, Res.NoApplicableIndexer,                GetTypeName(expr.Type));            case 1:              return Expression.Call(expr, (MethodInfo)mb, args);            default:              throw ParseError(errorPos, Res.AmbiguousIndexerInvocation,                GetTypeName(expr.Type));          }        }      }      static bool IsPredefinedType(Type type)      {        foreach (Type t in predefinedTypes) if (t == type) return true;        return false;      }      static bool IsNullableType(Type type)      {        return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>);      }      static Type GetNonNullableType(Type type)      {        return IsNullableType(type) ? type.GetGenericArguments()[0] : type;      }      static string GetTypeName(Type type)      {        Type baseType = GetNonNullableType(type);        string s = baseType.Name;        if (type != baseType) s += '?';        return s;      }      static bool IsNumericType(Type type)      {        return GetNumericTypeKind(type) != 0;      }      static bool IsSignedIntegralType(Type type)      {        return GetNumericTypeKind(type) == 2;      }      static bool IsUnsignedIntegralType(Type type)      {        return GetNumericTypeKind(type) == 3;      }      static int GetNumericTypeKind(Type type)      {        type = GetNonNullableType(type);        if (type.IsEnum) return 0;        switch (Type.GetTypeCode(type))        {          case TypeCode.Char:          case TypeCode.Single:          case TypeCode.Double:          case TypeCode.Decimal:            return 1;          case TypeCode.SByte:          case TypeCode.Int16:          case TypeCode.Int32:          case TypeCode.Int64:            return 2;          case TypeCode.Byte:          case TypeCode.UInt16:          case TypeCode.UInt32:          case TypeCode.UInt64:            return 3;          default:            return 0;        }      }      static bool IsEnumType(Type type)      {        return GetNonNullableType(type).IsEnum;      }      void CheckAndPromoteOperand(Type signatures, string opName, ref Expression expr, int errorPos)      {        Expression[] args = new Expression[] { expr };        MethodBase method;        if (FindMethod(signatures, "F", false, args, out method) != 1)          throw ParseError(errorPos, Res.IncompatibleOperand,            opName, GetTypeName(args[0].Type));        expr = args[0];      }      void CheckAndPromoteOperands(Type signatures, string opName, ref Expression left, ref Expression right, int errorPos)      {        Expression[] args = new Expression[] { left, right };        MethodBase method;        if (FindMethod(signatures, "F", false, args, out method) != 1)          throw IncompatibleOperandsError(opName, left, right, errorPos);        left = args[0];        right = args[1];      }      Exception IncompatibleOperandsError(string opName, Expression left, Expression right, int pos)      {        return ParseError(pos, Res.IncompatibleOperands,          opName, GetTypeName(left.Type), GetTypeName(right.Type));      }      MemberInfo FindPropertyOrField(Type type, string memberName, bool staticAccess)      {        BindingFlags flags = BindingFlags.Public | BindingFlags.DeclaredOnly |          (staticAccess ? BindingFlags.Static : BindingFlags.Instance);        foreach (Type t in SelfAndBaseTypes(type))        {          MemberInfo[] members = t.FindMembers(MemberTypes.Property | MemberTypes.Field,            flags, Type.FilterNameIgnoreCase, memberName);          if (members.Length != 0) return members[0];        }        return null;      }      int FindMethod(Type type, string methodName, bool staticAccess, Expression[] args, out MethodBase method)      {        BindingFlags flags = BindingFlags.Public | BindingFlags.DeclaredOnly |          (staticAccess ? BindingFlags.Static : BindingFlags.Instance);        foreach (Type t in SelfAndBaseTypes(type))        {          MemberInfo[] members = t.FindMembers(MemberTypes.Method,            flags, Type.FilterNameIgnoreCase, methodName);          int count = FindBestMethod(members.Cast<MethodBase>(), args, out method);          if (count != 0) return count;        }        method = null;        return 0;      }      int FindIndexer(Type type, Expression[] args, out MethodBase method)      {        foreach (Type t in SelfAndBaseTypes(type))        {          MemberInfo[] members = t.GetDefaultMembers();          if (members.Length != 0)          {            IEnumerable<MethodBase> methods = members.              OfType<PropertyInfo>().              Select(p => (MethodBase)p.GetGetMethod()).              Where(m => m != null);            int count = FindBestMethod(methods, args, out method);            if (count != 0) return count;          }        }        method = null;        return 0;      }      static IEnumerable<Type> SelfAndBaseTypes(Type type)      {        if (type.IsInterface)        {          List<Type> types = new List<Type>();          AddInterface(types, type);          return types;        }        return SelfAndBaseClasses(type);      }      static IEnumerable<Type> SelfAndBaseClasses(Type type)      {        while (type != null)        {          yield return type;          type = type.BaseType;        }      }      static void AddInterface(List<Type> types, Type type)      {        if (!types.Contains(type))        {          types.Add(type);          foreach (Type t in type.GetInterfaces()) AddInterface(types, t);        }      }      class MethodData      {        public MethodBase MethodBase;        public ParameterInfo[] Parameters;        public Expression[] Args;      }      int FindBestMethod(IEnumerable<MethodBase> methods, Expression[] args, out MethodBase method)      {        MethodData[] applicable = methods.          Select(m => new MethodData { MethodBase = m, Parameters = m.GetParameters() }).          Where(m => IsApplicable(m, args)).          ToArray();        if (applicable.Length > 1)        {          applicable = applicable.            Where(m => applicable.All(n => m == n || IsBetterThan(args, m, n))).            ToArray();        }        if (applicable.Length == 1)        {          MethodData md = applicable[0];          for (int i = 0; i < args.Length; i++) args[i] = md.Args[i];          method = md.MethodBase;        }        else        {          method = null;        }        return applicable.Length;      }      bool IsApplicable(MethodData method, Expression[] args)      {        if (method.Parameters.Length != args.Length) return false;        Expression[] promotedArgs = new Expression[args.Length];        for (int i = 0; i < args.Length; i++)        {          ParameterInfo pi = method.Parameters[i];          if (pi.IsOut) return false;          Expression promoted = PromoteExpression(args[i], pi.ParameterType, false);          if (promoted == null) return false;          promotedArgs[i] = promoted;        }        method.Args = promotedArgs;        return true;      }      Expression PromoteExpression(Expression expr, Type type, bool exact)      {        if (expr.Type == type) return expr;        if (expr is ConstantExpression)        {          ConstantExpression ce = (ConstantExpression)expr;          if (ce == nullLiteral)          {            if (!type.IsValueType || IsNullableType(type))              return Expression.Constant(null, type);          }          else          {            string text;            if (literals.TryGetValue(ce, out text))            {              Type target = GetNonNullableType(type);              Object value = null;              switch (Type.GetTypeCode(ce.Type))              {                case TypeCode.Int32:                case TypeCode.UInt32:                case TypeCode.Int64:                case TypeCode.UInt64:                  value = ParseNumber(text, target);                  break;                case TypeCode.Double:                  if (target == typeof(decimal)) value = ParseNumber(text, target);                  break;                case TypeCode.String:                  value = ParseEnum(text, target);                  break;              }              if (value != null)                return Expression.Constant(value, type);            }          }        }        if (IsCompatibleWith(expr.Type, type))        {          if (type.IsValueType || exact) return Expression.Convert(expr, type);          return expr;        }        return null;      }      static object ParseNumber(string text, Type type)      {        switch (Type.GetTypeCode(GetNonNullableType(type)))        {          case TypeCode.SByte:            sbyte sb;            if (sbyte.TryParse(text, out sb)) return sb;            break;          case TypeCode.Byte:            byte b;            if (byte.TryParse(text, out b)) return b;            break;          case TypeCode.Int16:            short s;            if (short.TryParse(text, out s)) return s;            break;          case TypeCode.UInt16:            ushort us;            if (ushort.TryParse(text, out us)) return us;            break;          case TypeCode.Int32:            int i;            if (int.TryParse(text, out i)) return i;            break;          case TypeCode.UInt32:            uint ui;            if (uint.TryParse(text, out ui)) return ui;            break;          case TypeCode.Int64:            long l;            if (long.TryParse(text, out l)) return l;            break;          case TypeCode.UInt64:            ulong ul;            if (ulong.TryParse(text, out ul)) return ul;            break;          case TypeCode.Single:            float f;            if (float.TryParse(text, out f)) return f;            break;          case TypeCode.Double:            double d;            if (double.TryParse(text, out d)) return d;            break;          case TypeCode.Decimal:            decimal e;            if (decimal.TryParse(text, out e)) return e;            break;        }        return null;      }      static object ParseEnum(string name, Type type)      {        if (type.IsEnum)        {          MemberInfo[] memberInfos = type.FindMembers(MemberTypes.Field,            BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Static,            Type.FilterNameIgnoreCase, name);          if (memberInfos.Length != 0) return ((FieldInfo)memberInfos[0]).GetValue(null);        }        return null;      }      static bool IsCompatibleWith(Type source, Type target)      {        if (source == target) return true;        if (!target.IsValueType) return target.IsAssignableFrom(source);        Type st = GetNonNullableType(source);        Type tt = GetNonNullableType(target);        if (st != source && tt == target) return false;        TypeCode sc = st.IsEnum ? TypeCode.Object : Type.GetTypeCode(st);        TypeCode tc = tt.IsEnum ? TypeCode.Object : Type.GetTypeCode(tt);        switch (sc)        {          case TypeCode.SByte:            switch (tc)            {              case TypeCode.SByte:              case TypeCode.Int16:              case TypeCode.Int32:              case TypeCode.Int64:              case TypeCode.Single:              case TypeCode.Double:              case TypeCode.Decimal:                return true;            }            break;          case TypeCode.Byte:            switch (tc)            {              case TypeCode.Byte:              case TypeCode.Int16:              case TypeCode.UInt16:              case TypeCode.Int32:              case TypeCode.UInt32:              case TypeCode.Int64:              case TypeCode.UInt64:              case TypeCode.Single:              case TypeCode.Double:              case TypeCode.Decimal:                return true;            }            break;          case TypeCode.Int16:            switch (tc)            {              case TypeCode.Int16:              case TypeCode.Int32:              case TypeCode.Int64:              case TypeCode.Single:              case TypeCode.Double:              case TypeCode.Decimal:                return true;            }            break;          case TypeCode.UInt16:            switch (tc)            {              case TypeCode.UInt16:              case TypeCode.Int32:              case TypeCode.UInt32:              case TypeCode.Int64:              case TypeCode.UInt64:              case TypeCode.Single:              case TypeCode.Double:              case TypeCode.Decimal:                return true;            }            break;          case TypeCode.Int32:            switch (tc)            {              case TypeCode.Int32:              case TypeCode.Int64:              case TypeCode.Single:              case TypeCode.Double:              case TypeCode.Decimal:                return true;            }            break;          case TypeCode.UInt32:            switch (tc)            {              case TypeCode.UInt32:              case TypeCode.Int64:              case TypeCode.UInt64:              case TypeCode.Single:              case TypeCode.Double:              case TypeCode.Decimal:                return true;            }            break;          case TypeCode.Int64:            switch (tc)            {              case TypeCode.Int64:              case TypeCode.Single:              case TypeCode.Double:              case TypeCode.Decimal:                return true;            }            break;          case TypeCode.UInt64:            switch (tc)            {              case TypeCode.UInt64:              case TypeCode.Single:              case TypeCode.Double:              case TypeCode.Decimal:                return true;            }            break;          case TypeCode.Single:            switch (tc)            {              case TypeCode.Single:              case TypeCode.Double:                return true;            }            break;          default:            if (st == tt) return true;            break;        }        return false;      }      static bool IsBetterThan(Expression[] args, MethodData m1, MethodData m2)      {        bool better = false;        for (int i = 0; i < args.Length; i++)        {          int c = CompareConversions(args[i].Type,            m1.Parameters[i].ParameterType,            m2.Parameters[i].ParameterType);          if (c < 0) return false;          if (c > 0) better = true;        }        return better;      }      // Return 1 if s -> t1 is a better conversion than s -> t2      // Return -1 if s -> t2 is a better conversion than s -> t1      // Return 0 if neither conversion is better      static int CompareConversions(Type s, Type t1, Type t2)      {        if (t1 == t2) return 0;        if (s == t1) return 1;        if (s == t2) return -1;        bool t1t2 = IsCompatibleWith(t1, t2);        bool t2t1 = IsCompatibleWith(t2, t1);        if (t1t2 && !t2t1) return 1;        if (t2t1 && !t1t2) return -1;        if (IsSignedIntegralType(t1) && IsUnsignedIntegralType(t2)) return 1;        if (IsSignedIntegralType(t2) && IsUnsignedIntegralType(t1)) return -1;        return 0;      }      Expression GenerateEqual(Expression left, Expression right)      {        return Expression.Equal(left, right);      }      Expression GenerateNotEqual(Expression left, Expression right)      {        return Expression.NotEqual(left, right);      }      Expression GenerateGreaterThan(Expression left, Expression right)      {        if (left.Type == typeof(string))        {          return Expression.GreaterThan(            GenerateStaticMethodCall("Compare", left, right),            Expression.Constant(0)          );        }        return Expression.GreaterThan(left, right);      }      Expression GenerateGreaterThanEqual(Expression left, Expression right)      {        if (left.Type == typeof(string))        {          return Expression.GreaterThanOrEqual(            GenerateStaticMethodCall("Compare", left, right),            Expression.Constant(0)          );        }        return Expression.GreaterThanOrEqual(left, right);      }      Expression GenerateLessThan(Expression left, Expression right)      {        if (left.Type == typeof(string))        {          return Expression.LessThan(            GenerateStaticMethodCall("Compare", left, right),            Expression.Constant(0)          );        }        return Expression.LessThan(left, right);      }      Expression GenerateLessThanEqual(Expression left, Expression right)      {        if (left.Type == typeof(string))        {          return Expression.LessThanOrEqual(            GenerateStaticMethodCall("Compare", left, right),            Expression.Constant(0)          );        }        return Expression.LessThanOrEqual(left, right);      }      Expression GenerateAdd(Expression left, Expression right)      {        if (left.Type == typeof(string) && right.Type == typeof(string))        {          return GenerateStaticMethodCall("Concat", left, right);        }        return Expression.Add(left, right);      }      Expression GenerateSubtract(Expression left, Expression right)      {        return Expression.Subtract(left, right);      }      Expression GenerateStringConcat(Expression left, Expression right)      {        return Expression.Call(          null,          typeof(string).GetMethod("Concat", new[] { typeof(object), typeof(object) }),          new[] { left, right });      }      MethodInfo GetStaticMethod(string methodName, Expression left, Expression right)      {        return left.Type.GetMethod(methodName, new[] { left.Type, right.Type });      }      Expression GenerateStaticMethodCall(string methodName, Expression left, Expression right)      {        return Expression.Call(null, GetStaticMethod(methodName, left, right), new[] { left, right });      }      void SetTextPos(int pos)      {        textPos = pos;        ch = textPos < textLen ? text[textPos] : '\0';      }      void NextChar()      {        if (textPos < textLen) textPos++;        ch = textPos < textLen ? text[textPos] : '\0';      }      void NextToken()      {        while (Char.IsWhiteSpace(ch)) NextChar();        TokenId t;        int tokenPos = textPos;        switch (ch)        {          case '!':            NextChar();            if (ch == '=')            {              NextChar();              t = TokenId.ExclamationEqual;            }            else            {              t = TokenId.Exclamation;            }            break;          case '%':            NextChar();            t = TokenId.Percent;            break;          case '&':            NextChar();            if (ch == '&')            {              NextChar();              t = TokenId.DoubleAmphersand;            }            else            {              t = TokenId.Amphersand;            }            break;          case '(':            NextChar();            t = TokenId.OpenParen;            break;          case ')':            NextChar();            t = TokenId.CloseParen;            break;          case '*':            NextChar();            t = TokenId.Asterisk;            break;          case '+':            NextChar();            t = TokenId.Plus;            break;          case ',':            NextChar();            t = TokenId.Comma;            break;          case '-':            NextChar();            t = TokenId.Minus;            break;          case '.':            NextChar();            t = TokenId.Dot;            break;          case '/':            NextChar();            t = TokenId.Slash;            break;          case ':':            NextChar();            t = TokenId.Colon;            break;          case '<':            NextChar();            if (ch == '=')            {              NextChar();              t = TokenId.LessThanEqual;            }            else if (ch == '>')            {              NextChar();              t = TokenId.LessGreater;            }            else            {              t = TokenId.LessThan;            }            break;          case '=':            NextChar();            if (ch == '=')            {              NextChar();              t = TokenId.DoubleEqual;            }            else            {              t = TokenId.Equal;            }            break;          case '>':            NextChar();            if (ch == '=')            {              NextChar();              t = TokenId.GreaterThanEqual;            }            else            {              t = TokenId.GreaterThan;            }            break;          case '?':            NextChar();            t = TokenId.Question;            break;          case '[':            NextChar();            t = TokenId.OpenBracket;            break;          case ']':            NextChar();            t = TokenId.CloseBracket;            break;          case '|':            NextChar();            if (ch == '|')            {              NextChar();              t = TokenId.DoubleBar;            }            else            {              t = TokenId.Bar;            }            break;          case '"':          case '\'':            char quote = ch;            do            {              NextChar();              while (textPos < textLen && ch != quote) NextChar();              if (textPos == textLen)                throw ParseError(textPos, Res.UnterminatedStringLiteral);              NextChar();            } while (ch == quote);            t = TokenId.StringLiteral;            break;          default:            if (Char.IsLetter(ch) || ch == '@' || ch == '_')            {              do              {                NextChar();              } while (Char.IsLetterOrDigit(ch) || ch == '_');              t = TokenId.Identifier;              break;            }            if (Char.IsDigit(ch))            {              t = TokenId.IntegerLiteral;              do              {                NextChar();              } while (Char.IsDigit(ch));              if (ch == '.')              {                t = TokenId.RealLiteral;                NextChar();                ValidateDigit();                do                {                  NextChar();                } while (Char.IsDigit(ch));              }              if (ch == 'E' || ch == 'e')              {                t = TokenId.RealLiteral;                NextChar();                if (ch == '+' || ch == '-') NextChar();                ValidateDigit();                do                {                  NextChar();                } while (Char.IsDigit(ch));              }              if (ch == 'F' || ch == 'f') NextChar();              break;            }            if (textPos == textLen)            {              t = TokenId.End;              break;            }            throw ParseError(textPos, Res.InvalidCharacter, ch);        }        token.id = t;        token.text = text.Substring(tokenPos, textPos - tokenPos);        token.pos = tokenPos;      }      bool TokenIdentifierIs(string id)      {        return token.id == TokenId.Identifier && String.Equals(id, token.text, StringComparison.OrdinalIgnoreCase);      }      string GetIdentifier()      {        ValidateToken(TokenId.Identifier, Res.IdentifierExpected);        string id = token.text;        if (id.Length > 1 && id[0] == '@') id = id.Substring(1);        return id;      }      void ValidateDigit()      {        if (!Char.IsDigit(ch)) throw ParseError(textPos, Res.DigitExpected);      }      void ValidateToken(TokenId t, string errorMessage)      {        if (token.id != t) throw ParseError(errorMessage);      }      void ValidateToken(TokenId t)      {        if (token.id != t) throw ParseError(Res.SyntaxError);      }      Exception ParseError(string format, params object[] args)      {        return ParseError(token.pos, format, args);      }      Exception ParseError(int pos, string format, params object[] args)      {        return new ParseException(string.Format(System.Globalization.CultureInfo.CurrentCulture, format, args), pos);      }      static Dictionary<string, object> CreateKeywords()      {        Dictionary<string, object> d = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);        d.Add("true", trueLiteral);        d.Add("false", falseLiteral);        d.Add("null", nullLiteral);        d.Add(keywordIt, keywordIt);        d.Add(keywordIif, keywordIif);        d.Add(keywordNew, keywordNew);        foreach (Type type in predefinedTypes) d.Add(type.Name, type);        return d;      }    }    static class Res    {      public const string DuplicateIdentifier = "The identifier '{0}' was defined more than once";      public const string ExpressionTypeMismatch = "Expression of type '{0}' expected";      public const string ExpressionExpected = "Expression expected";      public const string InvalidCharacterLiteral = "Character literal must contain exactly one character";      public const string InvalidIntegerLiteral = "Invalid integer literal '{0}'";      public const string InvalidRealLiteral = "Invalid real literal '{0}'";      public const string UnknownIdentifier = "Unknown identifier '{0}'";      public const string NoItInScope = "No 'it' is in scope";      public const string IifRequiresThreeArgs = "The 'iif' function requires three arguments";      public const string FirstExprMustBeBool = "The first expression must be of type 'Boolean'";      public const string BothTypesConvertToOther = "Both of the types '{0}' and '{1}' convert to the other";      public const string NeitherTypeConvertsToOther = "Neither of the types '{0}' and '{1}' converts to the other";      public const string MissingAsClause = "Expression is missing an 'as' clause";      public const string ArgsIncompatibleWithLambda = "Argument list incompatible with lambda expression";      public const string TypeHasNoNullableForm = "Type '{0}' has no nullable form";      public const string NoMatchingConstructor = "No matching constructor in type '{0}'";      public const string AmbiguousConstructorInvocation = "Ambiguous invocation of '{0}' constructor";      public const string CannotConvertValue = "A value of type '{0}' cannot be converted to type '{1}'";      public const string NoApplicableMethod = "No applicable method '{0}' exists in type '{1}'";      public const string MethodsAreInaccessible = "Methods on type '{0}' are not accessible";      public const string MethodIsVoid = "Method '{0}' in type '{1}' does not return a value";      public const string AmbiguousMethodInvocation = "Ambiguous invocation of method '{0}' in type '{1}'";      public const string UnknownPropertyOrField = "No property or field '{0}' exists in type '{1}'";      public const string NoApplicableAggregate = "No applicable aggregate method '{0}' exists";      public const string CannotIndexMultiDimArray = "Indexing of multi-dimensional arrays is not supported";      public const string InvalidIndex = "Array index must be an integer expression";      public const string NoApplicableIndexer = "No applicable indexer exists in type '{0}'";      public const string AmbiguousIndexerInvocation = "Ambiguous invocation of indexer in type '{0}'";      public const string IncompatibleOperand = "Operator '{0}' incompatible with operand type '{1}'";      public const string IncompatibleOperands = "Operator '{0}' incompatible with operand types '{1}' and '{2}'";      public const string UnterminatedStringLiteral = "Unterminated string literal";      public const string InvalidCharacter = "Syntax error '{0}'";      public const string DigitExpected = "Digit expected";      public const string SyntaxError = "Syntax error";      public const string TokenExpected = "{0} expected";      public const string ParseExceptionFormat = "{0} (at index {1})";      public const string ColonExpected = "':' expected";      public const string OpenParenExpected = "'(' expected";      public const string CloseParenOrOperatorExpected = "')' or operator expected";      public const string CloseParenOrCommaExpected = "')' or ',' expected";      public const string DotOrOpenParenExpected = "'.' or '(' expected";      public const string OpenBracketExpected = "'[' expected";      public const string CloseBracketOrCommaExpected = "']' or ',' expected";      public const string IdentifierExpected = "Identifier expected";    }

此时,我们需要将我们的实体和数据库字段映射对应起来,新建一个ImageMap类代码如下:

public class ImageMap : EntityTypeConfiguration<ImageModel>    {      public ImageMap()      {         // Primary Key        this.HasKey(t => t.ID);        // Properties        this.Property(t => t.IDProofFront)          .HasMaxLength(100);        this.Property(t => t.IDProofBack)          .HasMaxLength(100);        // Table & Column Mappings        this.ToTable("ImageModel");        this.Property(t => t.ID).HasColumnName("ID");        this.Property(t => t.IDProofFront).HasColumnName("IDProofFront");        this.Property(t => t.IDProofBack).HasColumnName("IDProofBack");      }    }

其中ToTable就是指明数据库表名,

那么如何将上传的图片保存更新到数据库呢?

接下来我们新建一个接口类IResourcesImage 并继承操作基类 IRepository<ImageModel>

定义一个上传身份信息的规则如下:

bool UpdateIDProof(string IDProofFront, string IDProofBack, int pId);

接下来我们新建一个ResourcesImage 实现上述接口。代码如下:

 public ResourcesImage() { }      /// <summary>      /// 上传身份信息采用此种方式      /// </summary>      /// <param name="IDProofBack"></param>      /// <param name="IDProofBack"></param>      /// <param name="pId"></param>      /// <returns></returns>      public bool UpdateIDProof(string IDProofFront, string IDProofBack, int pId)      {        int flag = 0;        if (IDProofFront != "" && IDProofFront != null)        {          flag = this.Update(m => m.ID == pId, u => new ImageModel { IDProofFront = IDProofFront });          if (flag == 1)          {            if (IDProofBack != "" && IDProofBack != null)              flag = this.Update(m => m.ID == pId, u => new ImageModel { IDProofBack = IDProofBack });          }        }        else        {          if (IDProofBack != "" && IDProofBack != null)            flag = this.Update(m => m.ID == pId, u => new ImageModel { IDProofBack = IDProofBack });        }        return flag == 0 ? false : true;      }

我们在中间层做一下这个操作:

 private readonly IResourcesImage _resourcesImage;      public CodeBLL()      {        this._resourcesImage = new ResourcesImage();      }      /// <summary>      /// 根据字段更新用户的文件资料信息      /// </summary>      /// <param name="fileNameField">字段</param>      /// <param name="fileNameValue">字段值</param>      /// <param name="pId"></param>      /// <returns></returns>      public bool UpdateFileName(string IDProofFront, string IDProofBack, int pId)      {        bool flag = false;        flag = _resourcesImage.UpdateIDProof(IDProofFront, IDProofBack, pId);        return flag;      }

这样做其实并不科学,需要手动实例化这种仓储操作,科学的方式可以使用IOC(控制反转).

中间层做好之后,我们只需要在HomeController中调用此方法即可,代码如下:

至此,我们就实现了本地通过ftp方式上传图片代码,并将图片以相对路径保存在数据库中,数据库存放格式如下:

以上就是C#中如何实现ftp图片上传功能的图文代码分享(必看)的详细内容,更多内容请关注技术你好其它相关文章!

来源链接:
免责声明:
1.资讯内容不构成投资建议,投资者应独立决策并自行承担风险
2.本文版权归属原作所有,仅代表作者本人观点,不代表本站的观点或立场
标签: 如何
上一篇:php获取远程图片并下载保存到本地的方法分析 下一篇:WPF实现好看的跑马灯特效实例

相关资讯