Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将实体转换为viewmodels以与web api一起使用_C#_Entity Framework_Asp.net Mvc 4_Asp.net Web Api - Fatal编程技术网

C# 将实体转换为viewmodels以与web api一起使用

C# 将实体转换为viewmodels以与web api一起使用,c#,entity-framework,asp.net-mvc-4,asp.net-web-api,C#,Entity Framework,Asp.net Mvc 4,Asp.net Web Api,我目前正在努力寻找一种更好的方法,用我的Entitiy对象填充我的ViewModel对象。我有以下webapicontroller方法: [HttpGet] public IEnumerable<ClientSearchViewModel> FindClients(string query) { var clients = _clientService.SearchClient(query).ToList(); var returnClients = new List

我目前正在努力寻找一种更好的方法,用我的
Entitiy
对象填充我的
ViewModel
对象。我有以下
webapi
controller方法:

[HttpGet]
public IEnumerable<ClientSearchViewModel> FindClients(string query)
{
    var clients = _clientService.SearchClient(query).ToList();
    var returnClients = new List<ClientSearchViewModel>();
    foreach (var client in clients)
    {
        returnClients.Add(new ClientSearchViewModel(client));
    }
    return returnClients;
}

除了查看返回对象列表并创建新的
ViewModel
列表之外,还有其他方法吗?

我强烈建议使用映射插件来实现此目的,例如:

这样的插件将允许您在内部或数据层中使用的对象与外部对象(DTO/ViewModels)之间进行映射。它们可以直接处理许多事情,例如自动映射具有相同类型的任何类似命名属性,但也允许在属性或类型的特定映射中进行大量控制,以便在需要更自定义的时候使用

为了对两者进行简单的比较,没有什么比听到作者自己的回答更好的了:


就我个人而言,我发现ValueInjector使用起来更快,同时总体控制能力更强,但我也发现它的可读性/直观性远不如AutoMapper,后者可能需要更多的代码才能实现类似的目标。因此,我会选择您和/或您的团队更喜欢的语法,以及您能够轻松掌握的概念和您真正需要的能力。

所以我有相同的miff。。。我不能说我已经测试了我的解决方案,但它似乎运行得相当快

3位:

public static T Transform<T>(this object convertFrom) where T : class, new()
        {
            return (T) (new ServiceExtension().Transform(convertFrom, typeof (T)));

        }

private class ServiceExtension
        {
            public object Transform(object convertFrom, Type convertTo)
            {
                object _t = Activator.CreateInstance(convertTo);
                if (convertFrom == null) return _t;

                var convertType = convertFrom.GetType();
            foreach (
                var property in _t.GetType().GetProperties().Where(f => f.CanWrite && f.GetSetMethod(true).IsPublic)
                )
            {
                if (property.GetCustomAttributes(typeof (TransformAttribute), true).Any())
                {
                    var transform =
                        (property.GetCustomAttributes(typeof (TransformAttribute), true).FirstOrDefault() as
                         TransformAttribute);
                    var transformname = transform.RelatedField ?? property.Name;

                    if (convertType.GetProperty(transformname) == null)
                        throw new ArgumentException(
                            string.Format(
                                "We were unable to find property:\"{0}\" on {1}.  Please check the RelativeField value on the {2} for \"{0}\"",
                                transformname, convertFrom.GetType().Name, convertTo.Name));

                    var theValue = convertType.GetProperty(transformname).GetValue(convertFrom);

                    if (isCollection(theValue))
                    {
                        foreach (var item in (theValue as ICollection))
                        {
                            var someVal = new object();
                            var newToType = property.PropertyType.GetGenericArguments().FirstOrDefault();

                            if (!String.IsNullOrEmpty(transform.FullyQualifiedName))
                                someVal =
                                    Transform(
                                        item.GetType().GetProperty(transform.FullyQualifiedName).GetValue(item),
                                        newToType);

                            else
                                someVal = Transform(item, newToType);
                            if (property.GetValue(_t) == null)
                                throw new NullReferenceException(
                                    string.Format(
                                        "The following property:{0} is null on {1}.  Likely this needs to be initialized inside of {1}'s empty constructor",
                                        property.Name, _t.GetType().Name));
                            property.PropertyType.GetMethod("Add")
                                    .Invoke(property.GetValue(_t), new[] {someVal});
                            //property.SetValue(_t, theValue.Transform(theValue.GetType()));
                        }
                    }
                    else
                        property.SetValue(_t, theValue);
                }
                //property.SetValue(_t, property.GetValue(convertFrom, null), null);
            }

            return _t;
        }

        public bool isCollection(object o)
        {
            return o is ICollection
                   || typeof (ICollection<>).IsInstanceOfType(o);
        }
    }


public class TransformAttribute : Attribute
    {
        public string RelatedField { get; private set; }
        public string FullyQualifiedName { get; set; }

    public TransformAttribute()
    {
    }

    public TransformAttribute(string relatedField)
    {
        RelatedField = relatedField;
    }

}
publicstatict转换(此对象转换自),其中T:class,new()
{
return(T)(newServiceExtension().Transform(convertFrom,typeof(T)));
}
私有类服务扩展
{
公共对象转换(对象convertFrom,类型convertTo)
{
对象_t=Activator.CreateInstance(convertTo);
if(convertFrom==null)返回_t;
var convertType=convertFrom.GetType();
弗雷奇(
_t.GetType().GetProperties()中的var属性,其中(f=>f.CanWrite&&f.GetSetMethod(true.IsPublic)
)
{
if(property.GetCustomAttributes(typeof(TransformAttribute),true).Any())
{
变量变换=
(property.GetCustomAttributes(typeof(TransformAttribute),true).FirstOrDefault()作为
转换属性);
var transformname=transform.RelatedField??property.Name;
if(convertType.GetProperty(transformname)==null)
抛出新的ArgumentException(
字符串格式(
“我们在{1}上找不到属性:\”{0}\。请检查{2}上的RelativeField值是否为\“{0}\”,
transformname,convertFrom.GetType().Name,convertTo.Name));
var theValue=convertType.GetProperty(transformname).GetValue(convertFrom);
如果(是集合(值))
{
foreach(中的var项目(作为ICollection的值))
{
var someVal=新对象();
var newToType=property.PropertyType.GetGenericArguments().FirstOrDefault();
如果(!String.IsNullOrEmpty(transform.FullyQualifiedName))
某地=
转化(
item.GetType().GetProperty(transform.FullyQualifiedName).GetValue(item),
新类型);
其他的
someVal=转换(项,新类型);
if(property.GetValue(\u t)==null)
抛出新的NullReferenceException(
字符串格式(
“以下属性:{0}在{1}上为空。这可能需要在{1}的空构造函数内初始化”,
property.Name,_t.GetType().Name));
property.PropertyType.GetMethod(“添加”)
.Invoke(property.GetValue(_t),new[]{someVal});
//属性.SetValue(_t,theValue.Transform(theValue.GetType());
}
}
其他的
属性设置值(_t,theValue);
}
//SetValue(_t,property.GetValue(convertFrom,null),null);
}
返回;;
}
公共布尔isCollection(对象o)
{
返回o是I集合
||typeof(i收集)。i安装类型(o);
}
}
公共类TransformAttribute:属性
{
公共字符串相关字段{get;private set;}
公共字符串FullyQualifiedName{get;set;}
公共属性()
{
}
公共转换属性(字符串相关字段)
{
RelatedField=RelatedField;
}
}
最终结果是:myObject.Transform()


但是这些装饰让您可以解释POCO和ViewModel之间的差异

个人是否喜欢其中一个?或者两者都有一些简单的优点和缺点?添加了一个链接,其中包含来自实际作者的更多信息。
public static T Transform<T>(this object convertFrom) where T : class, new()
        {
            return (T) (new ServiceExtension().Transform(convertFrom, typeof (T)));

        }

private class ServiceExtension
        {
            public object Transform(object convertFrom, Type convertTo)
            {
                object _t = Activator.CreateInstance(convertTo);
                if (convertFrom == null) return _t;

                var convertType = convertFrom.GetType();
            foreach (
                var property in _t.GetType().GetProperties().Where(f => f.CanWrite && f.GetSetMethod(true).IsPublic)
                )
            {
                if (property.GetCustomAttributes(typeof (TransformAttribute), true).Any())
                {
                    var transform =
                        (property.GetCustomAttributes(typeof (TransformAttribute), true).FirstOrDefault() as
                         TransformAttribute);
                    var transformname = transform.RelatedField ?? property.Name;

                    if (convertType.GetProperty(transformname) == null)
                        throw new ArgumentException(
                            string.Format(
                                "We were unable to find property:\"{0}\" on {1}.  Please check the RelativeField value on the {2} for \"{0}\"",
                                transformname, convertFrom.GetType().Name, convertTo.Name));

                    var theValue = convertType.GetProperty(transformname).GetValue(convertFrom);

                    if (isCollection(theValue))
                    {
                        foreach (var item in (theValue as ICollection))
                        {
                            var someVal = new object();
                            var newToType = property.PropertyType.GetGenericArguments().FirstOrDefault();

                            if (!String.IsNullOrEmpty(transform.FullyQualifiedName))
                                someVal =
                                    Transform(
                                        item.GetType().GetProperty(transform.FullyQualifiedName).GetValue(item),
                                        newToType);

                            else
                                someVal = Transform(item, newToType);
                            if (property.GetValue(_t) == null)
                                throw new NullReferenceException(
                                    string.Format(
                                        "The following property:{0} is null on {1}.  Likely this needs to be initialized inside of {1}'s empty constructor",
                                        property.Name, _t.GetType().Name));
                            property.PropertyType.GetMethod("Add")
                                    .Invoke(property.GetValue(_t), new[] {someVal});
                            //property.SetValue(_t, theValue.Transform(theValue.GetType()));
                        }
                    }
                    else
                        property.SetValue(_t, theValue);
                }
                //property.SetValue(_t, property.GetValue(convertFrom, null), null);
            }

            return _t;
        }

        public bool isCollection(object o)
        {
            return o is ICollection
                   || typeof (ICollection<>).IsInstanceOfType(o);
        }
    }


public class TransformAttribute : Attribute
    {
        public string RelatedField { get; private set; }
        public string FullyQualifiedName { get; set; }

    public TransformAttribute()
    {
    }

    public TransformAttribute(string relatedField)
    {
        RelatedField = relatedField;
    }

}