ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

.NET 文件系统(五)--主表主键获取,获取子表类型,主表的存储与子表验证实现

2022-09-12 23:30:59  阅读:170  来源: 互联网

标签:return FileDownLoadSystem System saveModel 获取 using 子表 主表 public


FileDownLoadSystem.Core

BaseService改造

Extensions文件夹新增扩展类:EntityPropertiesExtensions

EntityPropertiesExtensions
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

namespace FileDownLoadSystem.Core.Extensions
{
	public static class EntityPropertiesExtensions
	{
		public static PropertyInfo GetKeyProperty(this Type entity)
		{
			return entity.GetProperties().GetKeyProperty();
		}
		public static PropertyInfo GetKeyProperty(this IEnumerable<PropertyInfo> propertyInfos)
		{
			return propertyInfos.Where(c => c.IsKey()).FirstOrDefault();
		}
		public static bool IsKey(this PropertyInfo property)
		{
			return property.GetCustomAttributes(typeof(KeyAttribute), false).Any();
		}
	}
}

拆分这么细的原因是为了考虑到以后会复用,所以拆成了三个方法

获取子表类型

在Entity层增加一个文件夹AttributeManager
新增一个类:EntityAttribute

EntityAttribute
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace FileDownLoadSystem.Entity.AttributeManager
{
	public class EntityAttribute : Attribute
	{
		/// <summary>
		/// 当前表的真实名称
		/// </summary>
		/// <value></value>
		public string TableName { get; set; }
		/// <summary>
		/// 表的中文名称
		/// </summary>
		/// <value></value>
		public string TableChineseName { get; set; }
		/// <summary>
		/// 明细表
		/// </summary>
		/// <value></value>
		public Type[] DetailTable { get; set; }
	}
}

BaseService 新增Update方法,改造如下

BaseService
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Reflection;
using System.Threading.Tasks;
using FileDownLoadSystem.Core.Enums;
using FileDownLoadSystem.Core.Extensions;
using FileDownLoadSystem.Core.Utility;
using FileDownLoadSystem.Entity;
using FileDownLoadSystem.Entity.AttributeManager;
using FileDownLoadSystem.Entity.Core;
using Microsoft.EntityFrameworkCore;

namespace FileDownLoadSystem.Core.BaseProvider
{

	public class BaseService<TModel, TRepository>
					where TModel : BaseModel
					where TRepository : IRepository<TModel>
	{
		protected readonly TRepository _repository;
		private WebResponseContent _responseContent;
		public BaseService(TRepository repository)
		{
			this._repository = repository;
			_responseContent = new(true);
		}
		public TModel FindFirst(Expression<Func<TModel, bool>> predicate,
			Expression<Func<TModel, Dictionary<object, QueryOrderBy>>> orderBy = null)
		{
			return _repository.FindFirst(predicate, orderBy);
		}
		public virtual WebResponseContent AddEntity(TModel entity)
		{
			return Add<TModel>(entity, null);
		}
		public WebResponseContent Add<TDetail>(TModel entity, List<TDetail> list = null)
			where TDetail : class
		{
			_repository.Insert(entity);
			// 保存明细
			if (list != null && list.Count > 0)
			{
				list.ForEach(item =>
				{
					//开启对当前对象的跟踪
					_repository.DbContext.Entry<TDetail>(item).State = EntityState.Added;

				});
				_repository.DbContext.SaveChanges();
			}
			_responseContent.OK(ResponseType.SaveSuccess);
			return _responseContent;
		}
		public WebResponseContent UpdateEntity<TDetail>(SaveModel saveModel)
			where TDetail : BaseModel
		{
			var datailList = saveModel.DetailData.DicToList<TDetail>();
			return default;
		}
		public WebResponse Update(SaveModel saveModel)
		{
			//获取主表类型
			var type = typeof(TModel);
			//主表主键的获取
			var mainKeyProperty = type.GetKeyProperty();
			Type detailType = null;
			if (saveModel.DetailData != null)
			{
				saveModel.DetailData = saveModel.DetailData == null
					? new List<Dictionary<string, object>>()
					: saveModel.DetailData.Where(x => x.Count > 0).ToList();
				//获取主表特性里的明细类型
				detailType = GetRealDetailType();
			}
			return default;
		}

		private Type? GetRealDetailType()
		{
			return typeof(TModel).GetCustomAttribute<EntityAttribute>()?.DetailTable?[0];
		}
	}
}

主要目的:为了获取主表特性里的明细类型

上端调用方式为:

WeatherForecastController

using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
using FileDownLoadSystem.Entity.Core;
using FileDownLoadSystem.Entity.FileInfo;
using FileDownLoadSystem.System.IRepositories;
using FileDownLoadSystem.System.IServices;
using Microsoft.AspNetCore.Mvc;

namespace FileDownLoadSystem.API.Controllers
{
	[ApiController]
	[Route("[controller]")]
	public class WeatherForecastController : ControllerBase
	{
		private static readonly string[] Summaries = new[]
		{
		"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
	};

		private readonly ILogger<WeatherForecastController> _logger;
		private readonly IFileService _fileRepository;

		public WeatherForecastController(ILogger<WeatherForecastController> logger, IFileService fileRepository)
		{
			this._fileRepository = fileRepository;
			_logger = logger;
		}
		[HttpGet(Name = "GetWeatherForecast")]
		public IEnumerable<WeatherForecast> Get()
		{
			var result = _fileRepository.Update(new SaveModel()
			{
				MainData = new Dictionary<string, object>()
				{
					{"Id",1},
					{"PublicDate",DateTime.Now}
				},
				DetailData = new List<Dictionary<string, object>>()
				{
					new Dictionary<string,object>(){
						{"FileId",1},
						{"PackageUrl","http://TreeSet.com"}
					}
				}
			});
			//1
			var res = _fileRepository.UpdateEntity<Files>(new SaveModel()
			{
				DetailData = new List<Dictionary<string, object>>()
				{
					new Dictionary<string,object>(){
						{"Id",1}
					}
				}
			});
			return Enumerable.Range(1, 5).Select(index => new WeatherForecast
			{
				Date = DateTime.Now.AddDays(index),
				TemperatureC = Random.Shared.Next(-20, 55),
				Summary = Summaries[Random.Shared.Next(Summaries.Length)]
			})
			.ToArray();
		}
	}
}

主表的存储

BaseService
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Reflection;
using System.Threading.Tasks;
using FileDownLoadSystem.Core.Enums;
using FileDownLoadSystem.Core.Extensions;
using FileDownLoadSystem.Core.Utility;
using FileDownLoadSystem.Entity;
using FileDownLoadSystem.Entity.AttributeManager;
using FileDownLoadSystem.Entity.Core;
using Microsoft.EntityFrameworkCore;

namespace FileDownLoadSystem.Core.BaseProvider
{

	public class BaseService<TModel, TRepository>
					where TModel : BaseModel
					where TRepository : IRepository<TModel>
	{
		protected readonly TRepository _repository;
		private WebResponseContent _responseContent;
		public BaseService(TRepository repository)
		{
			this._repository = repository;
			_responseContent = new(true);
		}
		public TModel FindFirst(Expression<Func<TModel, bool>> predicate,
			Expression<Func<TModel, Dictionary<object, QueryOrderBy>>> orderBy = null)
		{
			return _repository.FindFirst(predicate, orderBy);
		}
		public virtual WebResponseContent AddEntity(TModel entity)
		{
			return Add<TModel>(entity, null);
		}
		public WebResponseContent Add<TDetail>(TModel entity, List<TDetail> list = null)
			where TDetail : class
		{
			_repository.Insert(entity);
			// 保存明细
			if (list != null && list.Count > 0)
			{
				list.ForEach(item =>
				{
					//开启对当前对象的跟踪
					_repository.DbContext.Entry<TDetail>(item).State = EntityState.Added;

				});
				_repository.DbContext.SaveChanges();
			}
			_responseContent.OK(ResponseType.SaveSuccess);
			return _responseContent;
		}
		public WebResponseContent UpdateEntity<TDetail>(SaveModel saveModel)
			where TDetail : BaseModel
		{
			var datailList = saveModel.DetailData.DicToList<TDetail>();
			return default;
		}
		public WebResponseContent Update(SaveModel saveModel)
		{
			//获取主表类型
			var type = typeof(TModel);
			//主表主键的获取
			var mainKeyProperty = type.GetKeyProperty();
			Type detailType = null;
			if (saveModel.DetailData != null)
			{
				saveModel.DetailData = saveModel.DetailData == null
					? new List<Dictionary<string, object>>()
					: saveModel.DetailData.Where(x => x.Count > 0).ToList();
				//获取主表特性里的明细类型
				detailType = GetRealDetailType();
			}
			if (mainKeyProperty == null
			|| !saveModel.MainData.ContainsKey(mainKeyProperty.Name)
			|| saveModel.MainData[mainKeyProperty.Name] == null)
			{
				return _responseContent.Error(ResponseType.NoKey);
			}
			if (detailType == null)
			{
				TModel mainEntity = saveModel.MainData.DicToEntity<TModel>();
				_repository.Update(mainEntity);
				_responseContent.OK(ResponseType.SaveSuccess);
				_responseContent.Data = new { data = mainEntity };
				return _responseContent;
			}
			return default;
		}

		private Type? GetRealDetailType()
		{
			return typeof(TModel).GetCustomAttribute<EntityAttribute>()?.DetailTable?[0];
		}
	}
}

上端调用修改:

WeatherForecastController

using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
using FileDownLoadSystem.Core.Utility;
using FileDownLoadSystem.Entity.Core;
using FileDownLoadSystem.Entity.FileInfo;
using FileDownLoadSystem.System.IRepositories;
using FileDownLoadSystem.System.IServices;
using Microsoft.AspNetCore.Mvc;

namespace FileDownLoadSystem.API.Controllers
{
	[ApiController]
	[Route("[controller]")]
	public class WeatherForecastController : ControllerBase
	{
		private static readonly string[] Summaries = new[]
		{
		"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
	};

		private readonly ILogger<WeatherForecastController> _logger;
		private readonly IFileService _fileRepository;

		public WeatherForecastController(ILogger<WeatherForecastController> logger, IFileService fileRepository)
		{
			this._fileRepository = fileRepository;
			_logger = logger;
		}
		[HttpGet(Name = "GetWeatherForecast")]
		public WebResponseContent Get()
		{
			var result = _fileRepository.Update(new SaveModel()
			{
				MainData = new Dictionary<string, object>()
				{
					{"PublicDate",DateTime.Now}
				},
				// DetailData = new List<Dictionary<string, object>>()
				// {
				// 	new Dictionary<string,object>(){
				// 		{"FileId",1},
				// 		{"PackageUrl","http://TreeSet.com"}
				// 	}
				// }
			});
			//1
			// var res = _fileRepository.UpdateEntity<Files>(new SaveModel()
			// {
			// 	DetailData = new List<Dictionary<string, object>>()
			// 	{
			// 		new Dictionary<string,object>(){
			// 			{"Id",1}
			// 		}
			// 	}
			// });
			return result;
		}
	}
}

子表验证实现

改造BaseService

BaseService
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Reflection;
using System.Threading.Tasks;
using FileDownLoadSystem.Core.Enums;
using FileDownLoadSystem.Core.Extensions;
using FileDownLoadSystem.Core.Utility;
using FileDownLoadSystem.Entity;
using FileDownLoadSystem.Entity.AttributeManager;
using FileDownLoadSystem.Entity.Core;
using Microsoft.EntityFrameworkCore;

namespace FileDownLoadSystem.Core.BaseProvider
{

	public class BaseService<TModel, TRepository>
					where TModel : BaseModel
					where TRepository : IRepository<TModel>
	{
		protected readonly TRepository _repository;
		private WebResponseContent _responseContent;
		public BaseService(TRepository repository)
		{
			this._repository = repository;
			_responseContent = new(true);
		}
		public TModel FindFirst(Expression<Func<TModel, bool>> predicate,
			Expression<Func<TModel, Dictionary<object, QueryOrderBy>>> orderBy = null)
		{
			return _repository.FindFirst(predicate, orderBy);
		}
		public virtual WebResponseContent AddEntity(TModel entity)
		{
			return Add<TModel>(entity, null);
		}
		public WebResponseContent Add<TDetail>(TModel entity, List<TDetail> list = null)
			where TDetail : class
		{
			_repository.Insert(entity);
			// 保存明细
			if (list != null && list.Count > 0)
			{
				list.ForEach(item =>
				{
					//开启对当前对象的跟踪
					_repository.DbContext.Entry<TDetail>(item).State = EntityState.Added;

				});
				_repository.DbContext.SaveChanges();
			}
			_responseContent.OK(ResponseType.SaveSuccess);
			return _responseContent;
		}
		public WebResponseContent UpdateEntity<TDetail>(
			SaveModel saveModel,
			PropertyInfo mainKeyProperty,
			PropertyInfo detailKeyInfo,
			object keyDefaultVal)
			where TDetail : BaseModel
		{
			var datailList = saveModel.DetailData.DicToList<TDetail>();
			return default;
		}
		public WebResponseContent Update(SaveModel saveModel)
		{
			//获取主表类型
			var type = typeof(TModel);
			//主表主键的获取
			var mainKeyProperty = type.GetKeyProperty();
			Type detailType = null;
			if (saveModel.DetailData != null)
			{
				saveModel.DetailData = saveModel.DetailData == null
					? new List<Dictionary<string, object>>()
					: saveModel.DetailData.Where(x => x.Count > 0).ToList();
				//获取主表特性里的明细类型
				detailType = GetRealDetailType();
			}
			if (mainKeyProperty == null
			|| !saveModel.MainData.ContainsKey(mainKeyProperty.Name)
			|| saveModel.MainData[mainKeyProperty.Name] == null)
			{
				return _responseContent.Error(ResponseType.NoKey);
			}
			if (detailType == null)
			{
				TModel mainEntity = saveModel.MainData.DicToEntity<TModel>();
				_repository.Update(mainEntity);
				_responseContent.OK(ResponseType.SaveSuccess);
				_responseContent.Data = new { data = mainEntity };
				return _responseContent;
			}
			var foreignKeyName = typeof(TModel).GetCustomAttribute<EntityAttribute>()?.ForeignKeyName;
			saveModel.DetailData = saveModel.DetailData.Where(x => x.Count > 0).ToList();
			PropertyInfo detailKeyInfo = detailType.GetKeyProperty();
			object keyDefaultVal = mainKeyProperty.PropertyType.Assembly.CreateInstance(mainKeyProperty.PropertyType.FullName);
			foreach (var dic in saveModel.DetailData)
			{
				object detailKeyDefaultVal = mainKeyProperty.PropertyType.Assembly.CreateInstance(detailKeyInfo.PropertyType.FullName);
				if (dic[detailKeyInfo.Name] == null)
				{
					return _responseContent.Error(ResponseType.NoKey);
				}
				string detailKeyValue = dic[detailKeyInfo.Name].ToString();
				//判断子表的主键值是否正确
				if (detailKeyValue != detailKeyDefaultVal.ToString()
				|| !dic.ContainsKey(foreignKeyName)
				|| dic[foreignKeyName] != null
				|| dic[foreignKeyName].ToString() == keyDefaultVal.ToString())
				{
					return _responseContent.Error($"{foreignKeyName} 是必须的");
				}
			}
			return this.GetType().GetMethod("UpdateEntity")
			.MakeGenericMethod(detailType)
			.Invoke(this, new object[] { saveModel, mainKeyProperty, detailKeyInfo, keyDefaultVal })
			as WebResponseContent;
		}

		private Type? GetRealDetailType()
		{
			return typeof(TModel).GetCustomAttribute<EntityAttribute>()?.DetailTable?[0];
		}
	}
}

标签:return,FileDownLoadSystem,System,saveModel,获取,using,子表,主表,public
来源: https://www.cnblogs.com/rookiewang/p/16684794.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有