回到目錄
之前我寫過關于XMLRepository倉儲的實作的文章,主要是針對XElement方式的,對于XML的結構,一般來說有兩種,一是使用節點方式的,我習慣稱為XElement方式,别一種是屬性方式的,我習慣稱為XAttribute,這兩種方式,我比較取向于後面的,好處就是更簡潔,将C#裡的類看作節點,而将C#裡的屬性看作是節點的每個特性(XAttribute),這種方式感覺更容易被人接受!
如果您還看不懂這兩方式指的是什麼,就看一下兩種方式的XML舉例吧
XElement方式
<User>
<id>1</id>
<name>zzl</name>
</User>
XAttribute方式
<User id="1" name="zzl" />
怎麼樣,第二種方式更簡潔吧,但要注意,XAttribute方式書寫時,需要為每個特性的值加雙引号的,因為linq to xml認為每個XAttribute都是字元型的,在進行操作時,你可以根據實體類型進行轉換的
下面看一下我為XAttribute方式進行封裝的Repository吧
XML2Repository.cs源代碼
/// <summary>
/// XML檔案資料倉儲
/// XML結構為Attribute
/// </summary>
/// <typeparam name="TEntity"></typeparam>
public class XML2Repository<TEntity> :
IRepository<TEntity>
where TEntity : XMLEntity, new()
{
XDocument _doc;
string _filePath;
static object lockObj = new object();
public XML2Repository(string filePath)
{
_filePath = filePath;
_doc = XDocument.Load(filePath);
}
public void Insert(TEntity item)
{
if (item == null)
throw new ArgumentException("The database entity can not be null.");
XElement db = new XElement(typeof(TEntity).Name);
foreach (var member in item.GetType()
.GetProperties()
.Where(i => i.PropertyType.IsValueType
|| i.PropertyType == typeof(String)))
{
db.Add(new XAttribute(member.Name, member.GetValue(item, null) ?? string.Empty));
}
_doc.Root.Add(db);
lock (lockObj)
{
_doc.Save(_filePath);
}
}
public void Delete(TEntity item)
{
if (item == null)
throw new ArgumentException("The database entity can not be null.");
XElement xe = (from db in _doc.Root.Elements(typeof(TEntity).Name)
where db.Attribute("RootID").Value == item.RootID
select db).Single() as XElement;
xe.Remove();
lock (lockObj)
{
_doc.Save(_filePath);
}
}
public void Update(TEntity item)
{
if (item == null)
throw new ArgumentException("The database entity can not be null.");
XElement xe = (from db in _doc.Root.Elements(typeof(TEntity).Name)
where db.Attribute("RootID").Value == item.RootID
select db).Single();
try
{
foreach (var member in item.GetType()
.GetProperties()
.Where(i => i.PropertyType.IsValueType
|| i.PropertyType == typeof(String)))
{
xe.SetAttributeValue(member.Name, member.GetValue(item, null) ?? string.Empty);
}
lock (lockObj)
{
_doc.Save(_filePath);
}
}
catch
{
throw;
}
}
public IQueryable<TEntity> GetModel()
{
IEnumerable<XElement> list = _doc.Root.Elements(typeof(TEntity).Name);
IList<TEntity> returnList = new List<TEntity>();
foreach (var item in list)
{
TEntity entity = new TEntity();
foreach (var member in entity.GetType()
.GetProperties()
.Where(i => i.PropertyType.IsValueType
|| i.PropertyType == typeof(String)))//隻找簡單類型的屬性
{
if (item.Attribute(member.Name) != null)
member.SetValue(entity, Convert.ChangeType(item.Attribute(member.Name).Value, member.PropertyType), null);//動态轉換為指定類型
}
returnList.Add(entity);
}
return returnList.AsQueryable();
}
public TEntity Find(params object[] id)
{
return GetModel().FirstOrDefault(i => i.RootID == Convert.ToString(id[0]));
}
public void SetDbContext(IUnitOfWork unitOfWork)
{
throw new NotImplementedException();
}
}
至此,對于XML的倉儲實作就已經完都講完了,而對于其它倉儲我也都在這前介紹過,其中包括EFRepsitory,LinqRepository,MemoryRepositoy,RedisRepository再加上今天的XMLRepository和XML2Repository一共六大倉儲了,感覺已經可以寫一篇
關于如何實作倉儲的文章了,哈哈。
作者:倉儲大叔,張占嶺,
榮譽:微軟MVP
QQ:853066980
支付寶掃一掃,為大叔打賞!
