C# ftp 圖片上傳多快好省
前言
此篇講到的是圖片上傳功能,每個網站必定會有這樣類似的功能,上傳文件、上傳圖片等等。那麼接下來,看看我們EF+uploadfile+ftp如何玩轉上傳圖片吧
效果預覽具體實現一個簡單資料庫 只有一個主鍵Id,一個身份證正面路徑和一個身份證背面路徑三個欄位。
首先呢,我們把實體類新建好如下:
public class ImageModel:BaseEntity
{
///
///
public int ID { get; set; }
///
///
public string IDProofFront { get; set; }
///
///
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代碼如下:
現在我們看頁面將會毫無樣式,所以我們先引用下樣式,這裡引用了bootstrap 和一個 style2.css ,引入樣式後 界面如下:
/*!
* 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
*
* 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}" ({size} KB) is too small and must be larger than {minSize} KB.",
msgSizeTooLarge: "文件 "{name}" ({size} KB) 超過了允許大小 {maxSize} KB.",
msgFilesTooLess: "你必須選擇最少 {n} {files} 來上傳. ",
msgFilesTooMany: "選擇的上傳文件個數 ({n}) 超出最大文件的限制個數 {m}.",
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: "錯誤而調整圖像大小。
{errors}
",
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: "拖拽文件到這裡 …
支持多文件同時上傳",
dropZoneClickTitle: "
(或點擊{files}按鈕選擇文件)",
fileActionSettings: {
removeTitle: "刪除文件",
uploadTitle: "上傳文件",
zoomTitle: "查看詳情",
dragTitle: "移動 / 重置",
indicatorNewTitle: "沒有上傳",
indicatorSuccessTitle: "上傳",
indicatorErrorTitle: "上傳錯誤",
indicatorLoadingTitle: "上傳 ..."
},
previewZoomButtonTitles: {
prev: "預覽上一個文件",
next: "預覽下一個文件",
toggleheader: "縮放",
fullscreen: "全屏",
borderless: "無邊界模式",
close: "關閉當前預覽"
}
};
})(window.jQuery);
View Code
好了,界面大概就整成這樣子,現在需要我們實現功能了。首先用JS將上傳控制項初始化一下:
//上傳控制項初始化
function initFileUpload {
$("#uploadfile").fileinput({
//uploadExtraData: { kvId: "10" },
language: "zh", //設置語言
showUpload: false, //是否顯示上傳按鈕
uploadAsync: true, //默認非同步上傳
showRemove: false,
autoReplace: true,
maxFileCount: 1,
maxFileSize: 10240,
dropZoneTitle: "拖拽文件到這裡 …
僅限.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");
});
}
View Code
然後再 載入頁面的時候調用這個初始化即可
$(function {
initFileUpload;
})FTP上傳操作
注意,再initFileUpload方法中 上傳了圖片,會自動訪問uploadUrl 這個url地址,存放圖片,我們先看看這個action如何通過ftp上傳指定伺服器的。
FileUpLoad方法如下
///
///
///
public ActionResult FileUpLoad
{
bool flag = false;
string msg = string.Empty;
int size = Convert.ToInt16(_fileSize) * 1024 * 1024;
try
{
Dictionary
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 = "網路異常,請稍後再試" });
}
}
View Code
其中 _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 上傳文件的方法 如下:
///
///
///
///
///
///
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上傳文件幫助類,大家可以直接照搬 ,代碼如下:
///
///
public class FTPUpFile
{
string Filetype = ConfigurationManager.AppSettings["FileType"];
string ipaddress = ConfigurationManager.AppSettings["IPaddress"];
string Username = ConfigurationManager.AppSettings["UserName"];
string Password = ConfigurationManager.AppSettings["Password"];
///
///
/// 上傳文件路徑
/// FTP伺服器的IP和埠
/// FTP伺服器下的哪個目錄
/// FTP用戶名
/// FTP密碼
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;
}
}
///
///
///
///
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
}
}
///
///
///
///
///
///
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
}
}
///
///
/// 要檢查的目錄的路徑
/// 要檢查的目錄名
///
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("
{
int index = datas[i].IndexOf("
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;
}
///
///
/// 文件的Byte數組
/// 文件原始名字(帶後綴名)
/// 新文件名的前綴
///
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;
}
}
///
/// 不修改名字及後綴名
///
/// 上傳文件的絕對路徑
///
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("");
}
}
///
///
///
///
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("");
}
}
///
///
/// 本地保存目錄路徑和文件名稱
/// FTP目錄路徑和文件名稱
///
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;
}
}
///
///
/// 需要上傳圖片
///
///
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
///
///
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;
}
}
View Code
值得注意的是:幫助類中也從配置文件中讀取了存放地址、文件類型、用戶名、密碼等必要信息。這個大家可以自己再配置文件中配置,配置好了如下所示:
還有一個類是圖片幫助類,代碼如下:
public class ImageHelper
{
///
///
/// 原圖路徑
/// 保存路徑
/// 壓縮質量(數字越小壓縮率越高) 1-100
/// 寬度
/// 高度
///
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);
}
///
///
/// 原圖流
/// 保存路徑
/// 壓縮質量(數字越小壓縮率越高) 1-100
/// 寬度
/// 高度
///
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
}
View Code
然後我們通過在fileuploaded的回調函數中綁定url即可顯示上傳後的圖片,效果如下圖:
不過這個只是上傳到ftp伺服器上了,並沒有保存到資料庫,現在我們要做的就是通過EF的方式將上傳的圖片保存到資料庫。
保存圖片首先我們要建一個操作的介面基類,並且還要約束成BaseEntity,代碼如下
public interface IRepository
{
///
///
///
/// (默認不跟蹤實體狀態)使用NoTracking的查詢會在性能方面得到改善
///
IQueryable
///
///
///
/// (默認不跟蹤實體狀態)使用NoTracking的查詢會在性能方面得到改善
///
///
IQueryable
IQueryable ///
/// ///
/// (默認不跟蹤實體狀態)使用NoTracking的查詢會在性能方面得到改善
/// /// /// The pageindex.
/// The pagesize.
/// 總條數
/// 條件謂詞
/// 排序,格式如:"Id"/"Id descending"
IQueryable /// /// The pageindex.
/// The pagesize.
/// 總條數
/// 條件謂詞
/// 排序,格式如:"Id"/"Id descending"
IQueryable /// int GetCount(Expression /// /// The entities.
/// 是否提交(true)
/// /// The entities.
/// 是否提交(true)
int Adds(List /// The entities.
/// 是否提交(true)
/// /// The entities.
/// 是否提交(true)
/// /// /// The where.
/// The entity.
int Update(Expression ///
int Delete(Expression /// /// sql
/// 參數
/// ///
/// /// /// /// ///
bool BeginTransaction(Func /// /// SQL語句或存儲過程 例如:exec usp_procedure
/// 參數列表
/// /// /// 存儲過程名
/// 參數列表
/// View Code 然後需要實現這個基類介面,代碼如下: public class BaseRepository private DbContext Context /// ///
/// (默認不跟蹤實體狀態)使用NoTracking的查詢會在性能方面得到改善
/// /// ///
/// (默認不跟蹤實體狀態)使用NoTracking的查詢會在性能方面得到改善
///
/// /// ///
/// /// ///
/// (默認不跟蹤實體狀態)使用NoTracking的查詢會在性能方面得到改善
/// /// /// The pageindex.
/// The pagesize.
/// 總條數
/// 條件謂詞
/// 排序,格式如:"Id"/"Id descending"
public IQueryable /// The pageindex.
/// The pagesize.
/// 總條數
/// 條件謂詞
/// 排序,格式如:"Id"/"Id descending"
public IQueryable public int GetCount(Expression /// /// The entities.
/// 是否提交(true)
/// Context.Entry /// /// The entities.
/// 是否提交(true)
public int Adds(List /// The entities.
/// 是否提交(true)
/// /// The entities.
/// 是否提交(true)
/// /// /// The where.
/// The entity.
public int Update(Expression /// ///
public int Delete(Expression /// /// sql
/// 參數
/// /// /// public bool BeginTransaction(Func } private IQueryable private IQueryable public IQueryable /// ///
/// /// /// SQL語句或存儲過程 例如:exec usp_procedure
/// 參數列表
/// conn.Close;//連接需要關閉 /// /// 存儲過程名
/// 參數列表
/// if (parameters != null && parameters.Length > 0) View Code 注意,我們在這個實現類中定義了一個私有方法,指明了資料庫訪問的上下文DbContext DbContext類如下: public class DbContext : System.Data.Entity.DbContext protected override void OnModelCreating(DbModelBuilder modelBuilder) View Code 我們將Name=DbContext 意思是去尋找webconfig中具有相同名稱的值 ,所以,我們在配置文件中配置該項如下: 再configuration節點下面新建 忘了說,這裡對實現類中的一些擴展方法做了延伸,新建一個DynamicQueryable類,代碼如下: public static class DynamicQueryable public static IQueryable Where(this IQueryable source, string predicate, params object[] values) public static IQueryable Select(this IQueryable source, string selector, params object[] values) public static IQueryable public static IQueryable ThenBy(this IQueryable source, string ordering, params object[] values) } public static IQueryable OrderBy(this IQueryable source, string ordering, params object[] values) public static IQueryable PropertyInfo property = type.GetProperty(propertyName); ParameterExpression param = Expression.Parameter(type, "p"); string methodName = ascending ? "OrderBy" : "OrderByDescending"; MethodCallExpression resultExp = Expression.Call(typeof(Queryable), methodName, return source.Provider.CreateQuery public static IQueryable Take(this IQueryable source, int count) public static IQueryable Skip(this IQueryable source, int count) public static IQueryable GroupBy(this IQueryable source, string keySelector, string elementSelector, params object[] values) public static bool Any(this IQueryable source) public static int Count(this IQueryable source) public abstract class DynamicClass public class DynamicProperty public DynamicProperty(string name, Type type) public string Name public Type Type public static class DynamicExpression public static LambdaExpression ParseLambda(Type itType, Type resultType, string expression, params object[] values) public static LambdaExpression ParseLambda(ParameterExpression[] parameters, Type resultType, string expression, params object[] values) public static Expression public static Type CreateClass(params DynamicProperty[] properties) public static Type CreateClass(IEnumerable internal class DynamicOrdering internal class Signature : IEquatable public Signature(IEnumerable public override int GetHashCode public override bool Equals(object obj) public bool Equals(Signature other) private ClassFactory public Type GetDynamicClass(IEnumerable Type CreateDynamicClass(DynamicProperty[] properties) FieldInfo GenerateProperties(TypeBuilder tb, DynamicProperty[] properties) void GenerateGetHashCode(TypeBuilder tb, FieldInfo[] fields) public sealed class ParseException : Exception public ParseException(string message, int position) public int Position public override string ToString internal class ExpressionParser enum TokenId interface ILogicalSignatures interface IArithmeticSignatures interface IRelationalSignatures : IArithmeticSignatures interface IEqualitySignatures : IRelationalSignatures interface IAddSignatures : IArithmeticSignatures interface ISubtractSignatures : IAddSignatures interface INegationSignatures interface INotSignatures interface IEnumerableSignatures static readonly Type predefinedTypes = { static readonly Expression trueLiteral = Expression.Constant(true); static readonly string keywordIt = "it"; static Dictionary Dictionary public ExpressionParser(ParameterExpression[] parameters, string expression, object[] values) void ProcessParameters(ParameterExpression[] parameters) void ProcessValues(object[] values) void AddSymbol(string name, object value) public Expression Parse(Type resultType) #pragma warning disable 0219 // ?: operator // ||, or operator // &&, and operator // =, ==, !=, <>, >, >=, <, <= 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.Divide(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 Expression GenerateConversion(Expression expr, Type type, int errorPos) Expression ParseMemberAccess(Type type, Expression instance) static Type FindGenericType(Type generic, Type type) Expression ParseAggregate(Expression instance, Type elementType, string methodName, int errorPos) Expression ParseArgumentList Expression ParseArguments Expression ParseElementAccess(Expression expr) static bool IsPredefinedType(Type type) static bool IsNullableType(Type type) static Type GetNonNullableType(Type type) static string GetTypeName(Type type) static bool IsNumericType(Type type) static bool IsSignedIntegralType(Type type) static bool IsUnsignedIntegralType(Type type) static int GetNumericTypeKind(Type type) static bool IsEnumType(Type type) void CheckAndPromoteOperand(Type signatures, string opName, ref Expression expr, int errorPos) void CheckAndPromoteOperands(Type signatures, string opName, ref Expression left, ref Expression right, int errorPos) Exception IncompatibleOperandsError(string opName, Expression left, Expression right, int pos) MemberInfo FindPropertyOrField(Type type, string memberName, bool staticAccess) int FindMethod(Type type, string methodName, bool staticAccess, Expression[] args, out MethodBase method) int FindIndexer(Type type, Expression[] args, out MethodBase method) static IEnumerable static IEnumerable static void AddInterface(List class MethodData int FindBestMethod(IEnumerable // Return 1 if s -> t1 is a better conversion than s -> t2 Expression GenerateEqual(Expression left, Expression right) Expression GenerateNotEqual(Expression left, Expression right) Expression GenerateGreaterThan(Expression left, Expression right) Expression GenerateGreaterThanEqual(Expression left, Expression right) Expression GenerateLessThan(Expression left, Expression right) Expression GenerateLessThanEqual(Expression left, Expression right) Expression GenerateAdd(Expression left, Expression right) Expression GenerateSubtract(Expression left, Expression right) Expression GenerateStringConcat(Expression left, Expression right) MethodInfo GetStaticMethod(string methodName, Expression left, Expression right) Expression GenerateStaticMethodCall(string methodName, Expression left, Expression right) void SetTextPos(int pos) void ValidateDigit void ValidateToken(TokenId t, string errorMessage) void ValidateToken(TokenId t) Exception ParseError(string format, params object[] args) Exception ParseError(int pos, string format, params object[] args) static Dictionary static class Res View Code 此時,我們需要將我們的實體和資料庫欄位映射對應起來,新建一個ImageMap類代碼如下: public class ImageMap : EntityTypeConfiguration // Properties this.Property(t => t.IDProofBack) // Table & Column Mappings 其中ToTable就是指明資料庫表名, 那麼如何將上傳的圖片保存更新到資料庫呢? 接下來我們新建一個介面類IResourcesImage 並繼承操作基類 IRepository 定義一個上傳身份信息的規則如下: bool UpdateIDProof(string IDProofFront, string IDProofBack, int pId); 接下來我們新建一個ResourcesImage 實現上述介面。代碼如下 public ResourcesImage { } ///
///
///
/// if (IDProofFront != "" && IDProofFront != null) 我們在中間層做一下這個操作: private readonly IResourcesImage _resourcesImage; /// 欄位
/// 欄位值
///
/// 這樣做其實並不科學,需要手動實例化這種倉儲操作,科學的方式可以使用IOC(控制反轉). 中間層做好之後,我們只需要在HomeController中調用此方法即可,代碼如下: 至此,我們就實現了本地通過ftp方式上傳圖片代碼,並將圖片以相對路徑保存在資料庫中,資料庫存放格式如下:
IDbSet
///
///
bool IsExist(Expression
///
///
T FindSingle(Expression
///
///
///
///
int Add(T entity, bool isComit = true);
///
///
///
///
int Update(T entity, bool isComit = true);
///
///
int Delete(T entity, bool isComit = true);
///
///
///
///
int ExecuteSqlCommand(string sql, params SqlParameter[] parameters);
///
///
DbRawSqlQuery
///
/// sql
/// 參數
///
IList
///
/// 返回Datatable數據集
///
DataTable SqlQueryForDataTable(string sql, DbParameter[] parameters);
///
[Obsolete("此方法已過時,請改用SqlQueryForDataTable")]
DataTable ExecuteForDataTable(string proName, IDataParameter[] parameters);
}
{
{
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;
}
}
///
public IQueryable
{
return Filter(exp, isNoTracking);
}
///
public IQueryable
{
return Filter(whereLambda, isNoTracking, values);
}
///
public bool IsExist(Expression
{
return Context.Set
}
///
public T FindSingle(Expression
{
return Filter(exp, isNoTracking).FirstOrDefault;
}
///
{
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;
}
///
///
{
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;
}
///
///
{
return Filter(exp).Count;
}
///
public int Add(T entity, bool isComit = true)
{
return isComit ? Context.SaveChanges : 0;
}
///
{
foreach (T item in entitis)
{
Context.Entry
}
return isComit ? Context.SaveChanges : 0;
}
///
///
public int Update(T entity, bool isComit = true)
{
Context.Entry(entity).State = System.Data.Entity.EntityState.Modified;
return isComit ? Context.SaveChanges : 0;
}
///
///
public int Delete(T entity, bool isComit = true)
{
Context.Set
return isComit ? Context.SaveChanges : 0;
}
///
{
return Context.Set
}
///
{
return Context.Set
}
///
public int ExecuteSqlCommand(string sql, params SqlParameter[] parameters)
{
return Context.Database.ExecuteSqlCommand(sql, parameters);
}
///
/// sql
/// 參數
///
public IList
{
return Context.Database.SqlQuery
}
{
using (var trans = Context.Database.BeginTransaction)
{
try
{
var result = fun;
trans.Commit;
return result;
}
catch (Exception)
{
trans.Rollback;
return false;
}
}
{
var dbSet = Context.Set
if (exp != null)
dbSet = dbSet.Where(exp);
if (isNoTracking)
dbSet = dbSet.AsNoTracking;
return dbSet;
}
{
var dbSet = Context.Set
if (whereLambda != null)
dbSet = dbSet.Where(whereLambda, values);
if (isNoTracking)
dbSet = dbSet.AsNoTracking;
return dbSet;
}
public IQueryable
{
get
{
return Find(whereLambda: null);
}
}
{
return Context.Set
}
public IDbSet
{
return Context.Set
}
///
public DbRawSqlQuery
{
try
{
return Context.Database.SqlQuery
}
catch (Exception ex)
{
throw ex;
}
}
/// 返回Datatable數據集
///
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);
return table;
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (conn.State == ConnectionState.Open)
conn.Close;
}
}
///
[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;
{
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;
}
}
}
{
static DbContext
{
//Database.SetInitializer(new CreateDatabaseIfNotExists
}
public DbContext
: base("Name=DbContext")
{
}
{
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);
}
}
}
{
public static IQueryable
{
return (IQueryable
}
{
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)));
}
{
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
{
return (IQueryable
}
public static IQueryable
{
return (IQueryable
}
{
return (IQueryable
}
{
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
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);
}
{
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
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);
}
where T : class
{
Type type = typeof(T);
if (property == null)
throw new ArgumentException("propertyName", "Not Exist");
Expression propertyAccessExpression = Expression.MakeMemberAccess(param, property);
LambdaExpression orderByExpression = Expression.Lambda(propertyAccessExpression, param);
new Type { type, property.PropertyType }, source.Expression, Expression.Quote(orderByExpression));
}
{
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)));
}
{
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)));
}
{
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)));
}
{
if (source == null) throw new ArgumentNullException("source");
return (bool)source.Provider.Execute(
Expression.Call(
typeof(Queryable), "Any",
new Type { source.ElementType }, source.Expression));
}
{
if (source == null) throw new ArgumentNullException("source");
return (int)source.Provider.Execute(
Expression.Call(
typeof(Queryable), "Count",
new Type { source.ElementType }, source.Expression));
}
}
{
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;
}
}
{
string name;
Type type;
{
if (name == null) throw new ArgumentNullException("name");
if (type == null) throw new ArgumentNullException("type");
this.name = name;
this.type = type;
}
{
get { return name; }
}
{
get { return type; }
}
}
{
public static Expression Parse(Type resultType, string expression, params object[] values)
{
ExpressionParser parser = new ExpressionParser(null, expression, values);
return parser.Parse(resultType);
}
{
return ParseLambda(new ParameterExpression { Expression.Parameter(itType, "") }, resultType, expression, values);
}
{
ExpressionParser parser = new ExpressionParser(parameters, expression, values);
return Expression.Lambda(parser.Parse(resultType), parameters);
}
{
return (Expression
}
{
return ClassFactory.Instance.GetDynamicClass(properties);
}
{
return ClassFactory.Instance.GetDynamicClass(properties);
}
}
{
public Expression Selector;
public bool Ascending;
}
{
public DynamicProperty properties;
public int hashCode;
{
this.properties = properties.ToArray;
hashCode = 0;
foreach (DynamicProperty p in properties)
{
hashCode ^= p.Name.GetHashCode ^ p.Type.GetHashCode;
}
}
{
return hashCode;
}
{
return obj is Signature ? Equals((Signature)obj) : false;
}
{
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
int classCount;
ReaderWriterLock rwLock;
{
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
rwLock = new ReaderWriterLock;
}
{
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;
}
}
{
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 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);
}
{
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);
}
}
{
int position;
: base(message)
{
this.position = position;
}
{
get { return position; }
}
{
return string.Format(Res.ParseExceptionFormat, Message, position);
}
}
{
struct Token
{
public TokenId id;
public string text;
public int pos;
}
{
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
}
{
void F(bool x, bool y);
void F(bool? x, bool? 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);
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(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);
}
{
void F(bool x, bool y);
void F(bool? x, bool? y);
}
{
void F(DateTime x, TimeSpan y);
void F(TimeSpan x, TimeSpan y);
void F(DateTime? x, TimeSpan? y);
void F(TimeSpan? x, TimeSpan? y);
}
{
void F(DateTime x, DateTime y);
void F(DateTime? x, DateTime? y);
}
{
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);
}
{
void F(bool x);
void F(bool? x);
}
{
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);
}
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 falseLiteral = Expression.Constant(false);
static readonly Expression nullLiteral = Expression.Constant(null);
static readonly string keywordIif = "iif";
static readonly string keywordNew = "new";
IDictionary
Dictionary
ParameterExpression it;
string text;
int textPos;
int textLen;
char ch;
Token token;
{
if (expression == null) throw new ArgumentNullException("expression");
if (keywords == null) keywords = CreateKeywords;
symbols = new Dictionary
literals = new Dictionary
if (parameters != null) ProcessParameters(parameters);
if (values != null) ProcessValues(values);
text = expression;
textLen = text.Length;
SetTextPos(0);
NextToken;
}
{
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];
}
{
for (int i = 0; i < values.Length; i++)
{
object value = values[i];
if (i == values.Length - 1 && value is IDictionary
{
externals = (IDictionary
}
else
{
AddSymbol("@" + i.ToString(System.Globalization.CultureInfo.InvariantCulture), value);
}
}
}
{
if (symbols.ContainsKey(name))
throw ParseError(Res.DuplicateIdentifier, name);
symbols.Add(name, value);
}
{
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;
}
public IEnumerable
{
List
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
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;
}
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;
}
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;
}
List
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);
}
{
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));
}
{
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);
}
}
{
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;
}
{
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);
}
{
ValidateToken(TokenId.OpenParen, Res.OpenParenExpected);
NextToken;
Expression args = token.id != TokenId.CloseParen ? ParseArguments : new Expression[0];
ValidateToken(TokenId.CloseParen, Res.CloseParenOrCommaExpected);
NextToken;
return args;
}
{
List
while (true)
{
argList.Add(ParseExpression);
if (token.id != TokenId.Comma) break;
NextToken;
}
return argList.ToArray;
}
{
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));
}
}
}
{
foreach (Type t in predefinedTypes) if (t == type) return true;
return false;
}
{
return type.IsGenericType && type.GetGenericTypeDefinition == typeof(Nullable<>);
}
{
return IsNullableType(type) ? type.GetGenericArguments[0] : type;
}
{
Type baseType = GetNonNullableType(type);
string s = baseType.Name;
if (type != baseType) s += "?";
return s;
}
{
return GetNumericTypeKind(type) != 0;
}
{
return GetNumericTypeKind(type) == 2;
}
{
return GetNumericTypeKind(type) == 3;
}
{
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;
}
}
{
return GetNonNullableType(type).IsEnum;
}
{
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];
}
{
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];
}
{
return ParseError(pos, Res.IncompatibleOperands,
opName, GetTypeName(left.Type), GetTypeName(right.Type));
}
{
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;
}
{
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
if (count != 0) return count;
}
method = null;
return 0;
}
{
foreach (Type t in SelfAndBaseTypes(type))
{
MemberInfo members = t.GetDefaultMembers;
if (members.Length != 0)
{
IEnumerable
OfType
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;
}
{
if (type.IsInterface)
{
List
AddInterface(types, type);
return types;
}
return SelfAndBaseClasses(type);
}
{
while (type != null)
{
yield return type;
type = type.BaseType;
}
}
{
if (!types.Contains(type))
{
types.Add(type);
foreach (Type t in type.GetInterfaces) AddInterface(types, t);
}
}
{
public MethodBase MethodBase;
public ParameterInfo Parameters;
public Expression Args;
}
{
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 -> 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;
}
{
return Expression.Equal(left, right);
}
{
return Expression.NotEqual(left, right);
}
{
if (left.Type == typeof(string))
{
return Expression.GreaterThan(
GenerateStaticMethodCall("Compare", left, right),
Expression.Constant(0)
);
}
return Expression.GreaterThan(left, right);
}
{
if (left.Type == typeof(string))
{
return Expression.GreaterThanOrEqual(
GenerateStaticMethodCall("Compare", left, right),
Expression.Constant(0)
);
}
return Expression.GreaterThanOrEqual(left, right);
}
{
if (left.Type == typeof(string))
{
return Expression.LessThan(
GenerateStaticMethodCall("Compare", left, right),
Expression.Constant(0)
);
}
return Expression.LessThan(left, right);
}
{
if (left.Type == typeof(string))
{
return Expression.LessThanOrEqual(
GenerateStaticMethodCall("Compare", left, right),
Expression.Constant(0)
);
}
return Expression.LessThanOrEqual(left, right);
}
{
if (left.Type == typeof(string) && right.Type == typeof(string))
{
return GenerateStaticMethodCall("Concat", left, right);
}
return Expression.Add(left, right);
}
{
return Expression.Subtract(left, right);
}
{
return Expression.Call(
null,
typeof(string).GetMethod("Concat", new { typeof(object), typeof(object) }),
new { left, right });
}
{
return left.Type.GetMethod(methodName, new[] { left.Type, right.Type });
}
{
return Expression.Call(null, GetStaticMethod(methodName, left, right), new { left, right });
}
{
textPos = pos;
ch = textPos < textLen ? text[textPos] : " ";
}
void NextChar
{
if (textPos < textLen) textPos++;
ch = textPos < textLen ? text[textPos] : " ";
}
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;
}
{
if (!Char.IsDigit(ch)) throw ParseError(textPos, Res.DigitExpected);
}
{
if (token.id != t) throw ParseError(errorMessage);
}
{
if (token.id != t) throw ParseError(Res.SyntaxError);
}
{
return ParseError(token.pos, format, args);
}
{
return new ParseException(string.Format(System.Globalization.CultureInfo.CurrentCulture, format, args), pos);
}
{
Dictionary
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;
}
}
{
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";
}
{
public ImageMap
{
// Primary Key
this.HasKey(t => t.ID);
this.Property(t => t.IDProofFront)
.HasMaxLength(100);
.HasMaxLength(100);
this.ToTable("ImageModel");
this.Property(t => t.ID).HasColumnName("ID");
this.Property(t => t.IDProofFront).HasColumnName("IDProofFront");
this.Property(t => t.IDProofBack).HasColumnName("IDProofBack");
}
}
///
///
public bool UpdateIDProof(string IDProofFront, string IDProofBack, int pId)
{
int flag = 0;
{
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;
}
public CodeBLL
{
this._resourcesImage = new ResourcesImage;
}
///
///
public bool UpdateFileName(string IDProofFront, string IDProofBack, int pId)
{
bool flag = false;
flag = _resourcesImage.UpdateIDProof(IDProofFront, IDProofBack, pId);
return flag;
}
※EF之通過不同條件查找去重複
※Github 開源:高效好用的對象間屬性拷貝工具:升訊威 Mapper
※Java 動態載入Jar包,並使用
※python每天一個小練習-強壯的密碼
TAG:科技優家 |
※如何多快好省地解決三餐:國外流行的meal prep是啥
※直擊MWC19上海:5G「多快好省」,華為一騎絕塵
※平民生物學實驗室的福音:一種「多快好省」的DNA組裝方法TEDA
※「多快好省」差個多!國產航母建造速度快、質量好、經費省
※多快好省 圖片批量壓縮和轉換
※如何多快好省地增肌?
※美媒首曝052D改型清晰照,一舉彌補最大短板,多快好省建造中
※都9102年了,看「基建狂魔」如何多快好省的造工事
※感受快樂拍打,學會「多快好省」地拍出痧!
※如何「多快好省」地做出一大桌子菜
※多快好省!明清古刀上的馬齒焊到底是啥?
※多快好省又有范!教你棒針手套+帽子的編織方法
※如何多快好省的拍出倫敦婚紗照
※多快好省,囤年貨,過新年,新金融與零售的雙贏
※如何多快好省的練出馬甲線和腹肌
※想在考場上多快好省地讀懂長難句?你只需要明白一個道理!
※多快好省!就是這麼牛,雞蛋+胡蘿蔔,煎餅也瘋狂
※2018婚姻法:如何儘快離婚?2種離婚方式哪個更加多快好省?
※「多快好省」造航母?美海軍考慮一次性採購2艘福特級航母
※心怡科技邢琳琳:數字物流要為客戶提供多快好省的價值