欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

如何两个对象数据比对

程序员文章站 2022-04-15 21:22:56
public partial class ModelStatusDictionary where T : new() { static readonly DynamicMethod _dynamicMethod = new DynamicMethod(); ///
 public partial class modelstatusdictionary<t> where t : new()
    {
        static readonly dynamicmethod<t> _dynamicmethod = new dynamicmethod<t>();

        /// <summary>
        /// 判断指定特性的属性
        /// </summary>
        /// <param name="obj">对象</param>
        /// <param name="nonstance">是否获取基类的属性</param>
        /// <param name="nonproperty">排除的属性</param>
        /// <returns></returns>
        public static (bool state, string message) modelverified(t obj, bool nonstance = true, icollection<string> nonproperty = null)
        {
            bool isempty = true;

            string msge = string.empty;

            var ps = typeof(t).getproperties();
            if (!nonstance)
                ps = typeof(t).getproperties(bindingflags.declaredonly | bindingflags.public | bindingflags.nonpublic | bindingflags.static | bindingflags.instance);
            if (nonproperty != null)
                ps = ps.where(x => !nonproperty.contains(x.name)).toarray();

            var vmodel = (from p in ps
                          where p.getcustomattribute<displaynameattribute>(true) != null
                          select new
                          {
                              name = p.name,
                              dname = p.getcustomattribute<displaynameattribute>(true).displayname,
                              velue = _dynamicmethod.getvalue(obj, p.name),

                          }).distinct().tolist();
            var fiel = vmodel.where(x => !isfield(x.velue)).tolist();
            if (fiel.count > 0)
            {
                isempty = false;
                msge = $"{string.join(",", fiel.select(x => x.dname).tolist())},required fields cannot be empty!";
            }
            return (isempty, msge);
        }
        /// <summary>
        /// 两个类型一样的对象做比较
        /// </summary>
        /// <param name="model">a</param>
        /// <param name="modeldata">b</param>
        public static (bool state, list<modelequaldictionary> dictionary) modelequals(t lastmodel, t newmodel)
        {
            bool isequals = true;
            var ps = typeof(t).getproperties();
            var _last = getobject(ps, lastmodel);// (from p in ps
            var _new = getobject(ps, newmodel);
            var fields = _new.except(_last).where(x => !string.isnullorwhitespace(x.dname)).select(x => new modelequaldictionary() { displayname = x.dname, lostvalue = _last.where(y => y.name == x.name).firstordefault().value, newvalue = x.value }).tolist();
            if (fields != null)
                if (fields.any())
                    isequals = false;
            return (isequals, fields);
        }

        static ienumerable<dynamic> getobject(propertyinfo[] property, object model) 
        {
            if (model == null)
            {
                model = new t();
            }
            var dy = (from p in property
                      where p.getcustomattribute<displaynameattribute>(true) != null
                      select new
                      {
                          name = p.name,
                          dname = p.getcustomattribute<displaynameattribute>(true).displayname,
                          value = getmodelvalue(model, p),
                      });
            return dy;
        }
        /// <summary>
        /// 两个类型一样的对象做比较
        /// </summary>
        /// <param name="model">a</param>
        /// <param name="modeldata">b</param>
        /// <param name="noproperty">c</param>
        public static (bool state, list<modelequaldictionary> dictionary) modelequal(t lastmodel, t newmodel,bool nonproperty = false,icollection<string> nonproperty = null)
        {
            bool isequals = true;
            var ps = typeof(t).getproperties();
            if (nonproperty != null)
            {
                ps = ps.where(x => !nonproperty.contains(x.name)).toarray();
            }        
            var _last = nonproperty ? getnonpropertymodel(ps,lastmodel): getmodel(ps, lastmodel);
            var _new = nonproperty ? getnonpropertymodel(ps, newmodel) : getmodel(ps, newmodel);
            var fields = _new.except(_last).select(x => new modelequaldictionary() { displayname = x.dname, lostvalue = _last.where(y => y.name == x.name).firstordefault().value, newvalue = x.value }).tolist();
            if (fields != null)
                if (fields.any())
                    isequals = false;
            return (isequals, fields);
        }

        static ienumerable<dynamic> getnonpropertymodel(propertyinfo[] property, object model)
        {
            var a = property.where(p => p.getcustomattribute<isrequiredattribute>(true) != null).tolist();
            var dy = (from p in property
                      where p.getcustomattribute<isrequiredattribute>(true) != null
                      select new
                      {
                          name = p.name,
                          dname = p.getcustomattribute<isrequiredattribute>(true).isrequired,
                          value = getmodelvalue(model, p),
                      });
            return dy;
        }

        static ienumerable<dynamic> getmodel(propertyinfo[] property, object model)
        {
            var a = property.where(p => p.getcustomattribute<isrequiredattribute>(true) != null).tolist();
            var dy = (from p in property
                      where p.getcustomattribute<isrequiredattribute>(true) != null
                      select new
                      {
                          name = p.name,
                          dname = p.getcustomattribute<isrequiredattribute>(true).isrequired,
                          value = getmodelvalue(model, p),
                      });
            return dy;
        }
        static object getmodelvalue(object obj, propertyinfo property)
        {
            object value = string.empty;
            if (getpropertytype(property.propertytype) == typeof(nullable))
            {
                var nextobj = obj.gettype().getproperty(property.name).getvalue(obj, null);
                if (property.propertytype.basetype.name == "enum")
                {
                    value = nextobj;
                }
                else if (nextobj != null)
                {
                    if (getpropertytype(nextobj.gettype()) == typeof(datetime))
                    {
                        value = nextobj;
                    }
                    else
                    {
                        var ps = nextobj.gettype().getproperties();
                        var thisobj = getobject(ps, nextobj);
                        value = string.join(",", thisobj ?? thisobj.select(x => x.value).tolist());
                    }
                }
            }
            else
            {
                value = obj.gettype().getproperty(property.name).getvalue(obj, null);
            }
            return value;
        }

        static bool isfield(object value)
        {
            if (value == null) return false;

            var val = value.gettype().tostring();
            switch (val)
            {
                case "system.boolean":
                    return value == null ? false : true;
                case "system.byte":
                    return value == null ? false : true;
                case "system.sbyte":
                    return value == null ? false : true;
                case "system.char":
                    return string.isnullorwhitespace(value.tostring()) ? false : true;
                case "system.decimal":
                    return value == null ? false : true;
                case "system.double":
                    return value == null ? false : true;
                case "system.single":
                    return value == null ? false : true;
                case "system.int32":
                    return value == null ? false : true;
                case "system.uint32":
                    return value == null ? false : true;
                case "system.int64":
                    return value == null ? false : true;
                case "system.uint64":
                    return value == null ? false : true;
                case "system.object":
                    return value == null ? false : true;
                case "system.int16":
                    return value == null ? false : true;
                case "system.uint16":
                    return value == null ? false : true;
                case "system.string":
                    return string.isnullorwhitespace(value.tostring()) ? false : true;
                case "system.datetime.date":
                    return value == null ? false : true;
                case "system.datetime":
                    return value == null ? false : true;
                case "system.guid":
                    return value == null ? false : true;
                default:
                    return true;
            }



        }

        static type getpropertytype(type obj)
        {
            if (obj == null) return typeof(dbnull);
            var val = obj.tostring();
            switch (val)
            {
                case "system.boolean":
                    return typeof(boolean);
                case "system.byte":
                    return typeof(byte);
                case "system.sbyte":
                    return typeof(sbyte);
                case "system.char":
                    return typeof(char);
                case "system.decimal":
                    return typeof(decimal);
                case "system.double":
                    return typeof(double);
                case "system.single":
                    return typeof(single);
                case "system.int32":
                    return typeof(int32);
                case "system.uint32":
                    return typeof(uint32);
                case "system.int64":
                    return typeof(int64);
                case "system.uint64":
                    return typeof(uint64);
                case "system.object":
                    return typeof(object);
                case "system.int16":
                    return typeof(int16);
                case "system.uint16":
                    return typeof(uint16);
                case "system.string":
                    return typeof(string);
                case "system.datetime.date":
                    return typeof(datetime);
                case "system.datetime":
                    return typeof(datetime);
                case "system.guid":
                    return typeof(guid);
                case "system.enum":
                    return typeof(enum);
                default:
                    return typeof(nullable);
            }
        }
    }
    public class modelequaldictionary
    {
        public string displayname { get; set; }
        public object lostvalue { get; set; }
        public object newvalue { get; set; }
    }