Automapper:如何忽略EF(VB.NET)中的导航属性

Automapper:如何忽略EF(VB.NET)中的导航属性,vb.net,entity-framework,automapper,Vb.net,Entity Framework,Automapper,我是EF和AutoMapper的新手,我正试图用它来创建一个web服务。如果我尝试直接序列化EF实体,导航属性会抛出错误,因为它们无法序列化。我想找到一种抑制它们的方法,我被告知最好的方法是创建POCO用作数据传输对象 (在这一点上,我想我也可以使用ADO.NET编写自己的DTO——EF不应该为我省去编写自己的类的麻烦吗?) 我已经向我推荐了AutoMapper,作为将EF实体自动映射到POCO的一种方法,因此我尝试在以下过程中使用它,加载POCO: Public Sub Load(ByVal

我是EF和AutoMapper的新手,我正试图用它来创建一个web服务。如果我尝试直接序列化EF实体,导航属性会抛出错误,因为它们无法序列化。我想找到一种抑制它们的方法,我被告知最好的方法是创建POCO用作数据传输对象

(在这一点上,我想我也可以使用ADO.NET编写自己的DTO——EF不应该为我省去编写自己的类的麻烦吗?)

我已经向我推荐了AutoMapper,作为将EF实体自动映射到POCO的一种方法,因此我尝试在以下过程中使用它,加载POCO:

Public Sub Load(ByVal lngUserId As Long)

    Dim query = From u In db.Users
                Where u.UserID = lngUserId
                Select u

    AutoMapper.Mapper.Map(query.FirstOrDefault(), Me)

End Sub
问题是,它又出现了一个与导航属性相关的错误,AutoMapper似乎不会自动忽略该错误

因此,我尝试添加这一行以强制AutoMapper忽略nav属性:

Dim oMap = Mapper.CreateMap(Of User, UserDto).ForSourceMember(Sub(src) src.tblUserFarms, Sub(opt) opt.Ignore())
(tblUserFarms为资产净值财产)

我从我找到的一个C#示例中转换了语法,但似乎.ForSourceMember的第一个参数不应该是Lambda表达式,而且我找不到一个好的示例来说明如何使用它


我是在使用正确的方法,还是应该尝试其他方法?我是否应该简单地删除所有导航属性以解决问题,并失去它们的好处?EF是这项工作的合适工具吗?

下面是我如何做的代码片段。在忽略的情况下,我避免了加载导航属性对象(也提高了性能)

public domain.Entities.UserProfile GetUserProfile(字符串用户名)
{
Mapper.CreateMap()
.FormMember(dest=>dest.BillingAddress,opt=>opt.Ignore())
.FormMember(dest=>dest.ShippingAddress,opt=>opt.Ignore())
.ForMember(dest=>dest.Orders,opt=>opt.Ignore())
.FormMember(dest=>dest.ShoppingCartItems,opt=>opt.Ignore());
Entities.UserProfile storedProfile=db.UserProfiles.FirstOrDefault(x=>x.UserName.Equals(UserName));
var profile=Mapper.Map(storedProfile);
回报曲线;
}
这就是我定义UserProfile的方式

 public class UserProfile
{
    public virtual int UserId { get; set; }
    public virtual string UserName { get; set; }
    public virtual string Prefix { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string MiddleName { get; set; }
    public virtual string LastName { get; set; }
    public virtual string EmailAddress { get; set; }
    public virtual string Company { get; set; }
    public virtual string PhoneNumber { get; set; }
    public virtual string FaxNumber { get; set; }

    private ICollection<ShoppingCartItem> _shoppingCartItems;
    private ICollection<Address> _addresses;
    private ICollection<Order> _orders;

    /// <summary>
    /// Default billing address
    /// </summary>
    public virtual Address BillingAddress { get; set; }

    /// <summary>
    /// Default shipping address
    /// </summary>
    public virtual Address ShippingAddress { get; set; }

    /// <summary>
    /// Gets or sets customer addresses
    /// </summary>
    public virtual ICollection<Address> Addresses
    {
        get { return _addresses ?? (_addresses = new List<Address>()); }
        protected set { _addresses = value; }
    }

    /// <summary>
    /// Gets or sets orders
    /// </summary>
    public virtual ICollection<Order> Orders
    {
        get { return _orders ?? (_orders = new List<Order>()); }
        protected set { _orders = value; }
    }

    /// <summary>
    /// Gets or sets shopping cart items
    /// </summary>
    public virtual ICollection<ShoppingCartItem> ShoppingCartItems
    {
        get { return _shoppingCartItems ?? (_shoppingCartItems = new List<ShoppingCartItem>()); }
        protected set { _shoppingCartItems = value; }
    }

}
公共类用户配置文件
{
公共虚拟int用户标识{get;set;}
公共虚拟字符串用户名{get;set;}
公共虚拟字符串前缀{get;set;}
公共虚拟字符串FirstName{get;set;}
公共虚拟字符串MiddleName{get;set;}
公共虚拟字符串LastName{get;set;}
公共虚拟字符串EmailAddress{get;set;}
公共虚拟字符串公司{get;set;}
公共虚拟字符串PhoneNumber{get;set;}
公共虚拟字符串FaxNumber{get;set;}
私人ICollection_购物车项目;
专用ICollection\u地址;
私人ICollection_订单;
/// 
///默认帐单地址
/// 
公共虚拟地址计费地址{get;set;}
/// 
///默认送货地址
/// 
公共虚拟地址ShippingAddress{get;set;}
/// 
///获取或设置客户地址
/// 
公共虚拟ICollection地址
{
获取{返回_地址???(_地址=新列表());}
受保护集{u addresses=value;}
}
/// 
///获取或设置订单
/// 
公共虚拟ICollection订单
{
获取{return _orders???(_orders=new List());}
受保护集{u orders=value;}
}
/// 
///获取或设置购物车项目
/// 
公共虚拟ICollection ShoppingCartItems
{
获取{return _shoppingcartimes???(_shoppingcartimes=new List());}
受保护集{u shoppingCartItems=value;}
}
}

此时,我不得不继续我的项目,因此我选择编写自己的映射代码,将一些to/from映射方法放入DTO,将导航属性从ICollections转换为需要的列表。这不是最优雅的解决方案,但它能让我完全掌控局面。是的,我已经得出结论,EF实际上根本没有节省我任何编码时间,我仍然需要编写同样多的管道代码-唯一的区别是我编写的是LINQ查询而不是SQL,并且可以选择以后更改RDBMS。感谢Geovani,我一定会花些时间尝试一下。不幸的是,我的项目进展太远,无法从我现在使用的自定义代码更改回Automapper。
 public class UserProfile
{
    public virtual int UserId { get; set; }
    public virtual string UserName { get; set; }
    public virtual string Prefix { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string MiddleName { get; set; }
    public virtual string LastName { get; set; }
    public virtual string EmailAddress { get; set; }
    public virtual string Company { get; set; }
    public virtual string PhoneNumber { get; set; }
    public virtual string FaxNumber { get; set; }

    private ICollection<ShoppingCartItem> _shoppingCartItems;
    private ICollection<Address> _addresses;
    private ICollection<Order> _orders;

    /// <summary>
    /// Default billing address
    /// </summary>
    public virtual Address BillingAddress { get; set; }

    /// <summary>
    /// Default shipping address
    /// </summary>
    public virtual Address ShippingAddress { get; set; }

    /// <summary>
    /// Gets or sets customer addresses
    /// </summary>
    public virtual ICollection<Address> Addresses
    {
        get { return _addresses ?? (_addresses = new List<Address>()); }
        protected set { _addresses = value; }
    }

    /// <summary>
    /// Gets or sets orders
    /// </summary>
    public virtual ICollection<Order> Orders
    {
        get { return _orders ?? (_orders = new List<Order>()); }
        protected set { _orders = value; }
    }

    /// <summary>
    /// Gets or sets shopping cart items
    /// </summary>
    public virtual ICollection<ShoppingCartItem> ShoppingCartItems
    {
        get { return _shoppingCartItems ?? (_shoppingCartItems = new List<ShoppingCartItem>()); }
        protected set { _shoppingCartItems = value; }
    }

}