近期由于項目需要,開始學習和使用WCF技術。初次瀏覽1種陌生技術領域,最多見的就是踩“坑”了。之前在博客園閱讀了WCF專家老A的博文,并且翻閱了其相干著作《WCF技術剖析》和《WCF全面解析》。但是在項目實際開發進程中,還是遇到了這樣和那樣的問題。1次踩到如此多的“坑”,讓我很震驚。因此決定在博客中開辟“踩坑填坑”系列博文,該類博文主要用于記錄在應用新技術開發進程中遇到的各種奇葩毛病,同時直接給出解決方案。然文中卻不會對問題的本源和解決方案進行詳細介紹,待后續有時間深入研究分析相干問題機理后再統1發文歸類到“日積月累”系列中。
由于WCF服務的宿主選用的是WinForm程序,所以需要在WCFServiceLib類庫中回調WinForm的函數進行界面刷新等操作,因此在構造ServiceHost對象時,采取的是
public ServiceHost(object singletonInstance, params Uri[] baseAddresses);
利用該構造函數時,要求在服務契約ServiceContract中添加行動束縛,即InstanceContextMode=InstanceContextMode.Single。上述毛病提示已很明確的指出了解決方案。具體的實例可以參考之前的博文。
WCF具體實現進程會將服務契約以接口情勢給出,并添加ServiceContract、OperationContract等屬性束縛。然后通過實現該接口來完成具體的WCF服務定義。此時需要注意的是WCF具體實現類中不需要添加ServiceContract、OperationContract等配置束縛。否則會彈出上述毛病提示。
簡單的給出1段示例代碼:
//服務契約的約定接口類
[ServiceContract]
public interface IWcfServiceTest
{
[OperationContract]
void wcfHelloWorld(string name);
}
//服務契約的具體實現類
public class WcfServiceTest:IWcfServiceTest
{
void wcfHelloWorld(string name)
{
Console.WriteLine(name+":HellowWorld");
}
}
與上面的ServiceContract坑類似,OperationContract在WCF服務具體實現類中也不需要重復設置。示例代碼如上述相同。
在WCF中需要定義數據契約(Data Contract),簡而言之就是通知服務雙方,在調用具體服務函數時如何來序列化參數。對枚舉類型的成員,需要額外注意1下。具體的實現方式是:
namespace WCFData
{
[DataContract]
public enum WCFEnum
{
[EnumMemeber]
WcfCFind=0,
[EnumMemeber]
WcfCStore=1,
[EnumMemeber]
WcfCMove=2
}
[DataContract]
public class WCFRequest
{
[DataMember]
public string PatientID{get;set;}
[DataMemeber]
public string PatientName{get;set;}
[DataMember]
public WCFEnum ReqType{get;set;]
}
}
對上述問題可參考下面兩篇博文WCF枚舉變量、WCF枚舉變量2。
Telerik與SQLite結合,可以順利開發簡單編寫的利用。但是在使用SQLite引擎時常常會出現毛病中斷。提示你添加System.Data.SQLite.dll的援用,雖然你已添加到了工程的“援用”中。
經過仔細搜索Telerik官方資料,發現其中已針對該問題給出了3種解決方案,具體的大家可以參照Telerik官方說明,這里我選擇的是硬編碼方式,具體代碼以下:
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
if (args.Name.StartsWith("System.Data.SQLite,"))
{
return typeof(System.Data.SQLite.SQLiteFactory).Assembly;
}
return null;
}
在使用WinForm來寄宿WCF服務時,會遇到綁定事件來刷新界面的情況,具體可參考博文中的示例。另外有時候會需要對剛添加到數據庫中的記錄進行更新,這就需要獲得記錄的PK值,在Telerik官方論壇中搜索了半天未果。
后來在具體嘗試時發現,當調用SaveChanges()函數保存修改后,與剛插入的記錄中的主鍵對應的對象的指定屬性值就是數據庫中該條記錄的主鍵,即PK值。
示例代碼以下:
//*********************Code First Model定義類*******************
public class Customer
{
public int ID { get; set; }
public string Name { get; set; }
public DateTime DateCreated { get; set; }
public string EmailAddress { get; set; }
}
//***************具體的映照關系,其中設置ID為主鍵****************
protected override IList<MappingConfiguration> PrepareMapping()
{
List<MappingConfiguration> configurations = new List<MappingConfiguration>();
var customerMapping = new MappingConfiguration<Customer>();
customerMapping.MapType(customer => new
{
ID = customer.ID,
Name = customer.Name,
EmailAddress = customer.EmailAddress,
DateCreated = customer.DateCreated
}).ToTable("Customer");
customerMapping.HasProperty(c => c.ID).IsIdentity();
configurations.Add(customerMapping);
return configurations;
}
public IQueryable<Customer> Customers
{
get
{
return this.GetAll<Customer>();
}
}
//*******************實際利用,Update更新數據庫*********************
using (EntitiesModel dbContext = new EntitiesModel())
{
// Update a category
Category category = dbContext.Categories.First();
category.CategoryName = "New Name";
// Create two new categories
Category newCategory1 = new Category();
newCategory1.CategoryName = "New Category";
Category newCategory2 = new Category();
newCategory2.CategoryName = "New Category2";
dbContext.Add(new Category[] { newCategory1, newCategory2 });
dbContext.SaveChanges();
//【zssure】:調用SaveChanges后數據庫中已完成插入操作,此時可以獲得到剛剛插入的記錄的主鍵ID值
Console.WriteLine("Category1的PrimaryKey是{0},Category2的PrimaryKey是{1}",newCategory1.ID,newCategory2.ID);
}
踩坑(Running)填坑(ZSSURE),是近期由于項目中遇到了大量奇葩問題而新開的系列博文,主要用于記錄開發進程中遇到的實際問題,并給出簡單的解決方案,并保證方案在本人運行環境下成功。后續待漸漸沉淀積累后會對其中的重點問題進行剖析,并發文到“日積(Running)月累(ZSSURE)”系列。
作者:zssure@163.com
時間:2015-04-08
上一篇 四城市十行業緊缺人才信息公布
下一篇 下一波浪潮物聯網什么時候才能到來