我是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甚至是适合这项工作的工具吗?
答案 0 :(得分:2)
下面是我一直在做的代码片段。在忽略的情况下,我避免了导航属性对象的加载(也提高了性能)。
public domain.Entities.UserProfile GetUserProfile(string userName)
{
Mapper.CreateMap<Entities.UserProfile, domain.Entities.UserProfile>()
.ForMember(dest => dest.BillingAddress, opt => opt.Ignore())
.ForMember(dest => dest.ShippingAddress, opt => opt.Ignore())
.ForMember(dest => dest.Orders, opt => opt.Ignore())
.ForMember(dest => dest.ShoppingCartItems, opt => opt.Ignore());
Entities.UserProfile storedProfile = db.UserProfiles.FirstOrDefault(x => x.UserName.Equals(userName));
var profile = Mapper.Map<Entities.UserProfile, domain.Entities.UserProfile>(storedProfile);
return profile;
}
这就是我定义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; }
}
}