我在将 POCO 对象投影到 DTO 对象时遇到了一些困难
我的 POCO 对象
public class LogEntry
{
public LogEntry()
{
this.Username = Environment.UserName;
this.LogNote = String.Empty;
var now = DateTime.Now;
this.LoginTime = now;
this.LastSeenInput = now;
this.ServerName = Environment.MachineName;
}
public int LogEntryId { get; set; }
[Required(AllowEmptyStrings = false)]
[Column(TypeName = "nvarchar")]
[MaxLength(64)]
public string Username { get; set; }
[Required(AllowEmptyStrings = true)]
[Column(TypeName = "varchar")]
[MaxLength(20)]
public string ServerName { get; set; }
public DateTime LoginTime { get; set; }
public TimeSpan ConnectedFor { get; set; }
public TimeSpan IdleFor { get; set; }
public DateTime? LastSeenInput { get; set; }
[Required(AllowEmptyStrings = true)]
public string LogNote { get; set; }
}
我的 DTO 对象
public sealed class ClientEventDTO
{
public int LogEntryId { get; set; }
public string Username { get; set; }
public string ServerName { get; set; }
public DateTime LoginTime { get; set; }
public TimeSpan ConnectedFor { get; set; }
public string LogNote { get; set; }
public TimeSpan IdleForWithLast { get; set; }
}
我想做的是我想IdleForWithLast
代表
public TimeSpan IdleForWithLast
{
get
{
var tmp = IdleFor;
if (LastSeenInput.HasValue)
tmp = tmp.Add(DateTime.Now - LastSeenInput.Value);
return tmp;
}
}
但是,当我这样做时
static void Main(string[] args)
{
Mapper.CreateMap<LogEntry, ClientEventDTO>()
.ForMember(dto => dto.IdleFor,
a => a.MapFrom(ent => ent.LastSeenInput == null ?
ent.IdleFor :
ent.IdleFor + (DateTime.Now - ent.LastSeenInput.Value)
)
);
Mapper.AssertConfigurationIsValid();
using (var ctx = new LoginHistoryContext())
{
var username = "Scott";
var query = ctx.LogEntries.Where(entry => entry.Username == username).Project().To<ClientEventDTO>();
var result = query.ToList();
Debugger.Break();
}
}
我得到以下异常
System.ArgumentException 未处理
HResult=-2147024809
Message=DbArithmeticExpression 参数必须具有数字通用类型。
源=系统.数据.实体
更改ent.IdleFor + (DateTime.Now - ent.LastSeenInput.Value)
为ent.IdleFor.Add(DateTime.Now - ent.LastSeenInput.Value)
只是给了我一个不同的例外
System.NotSupportedException 未处理
HResult=-2146233067
Message=LINQ to Entities 无法识别方法 'System.TimeSpan Add(System.TimeSpan)' 方法,并且此方法无法转换为存储表达式。
源=系统.数据.实体
在保持兼容性的同时使用这种操作的正确方法是什么QueryableExtensions
?
如果您不关心兼容性,可以通过这种方式轻松完成
static void Main(string[] args)
{
Mapper.CreateMap<LogEntry, ClientEventDTO>()
.ForMember(dto => dto.IdleFor, opt=>opt.ResolveUsing<CustomResolver>());
Mapper.AssertConfigurationIsValid();
using (var ctx = new LoginHistoryContext())
{
var username = "Scott";
var query = ctx.LogEntries.Where(entry => entry.Username == username);
var result = Mapper.Map<List<ClientEventDTO>>(query.ToList());
Debugger.Break();
}
}
public class CustomResolver : ValueResolver<LogEntry, TimeSpan>
{
protected override TimeSpan ResolveCore(LogEntry source)
{
var tmp = source.IdleFor;
if (source.LastSeenInput.HasValue)
tmp = tmp.Add(DateTime.Now - source.LastSeenInput.Value);
return tmp;
}
}
这就是我可能会在这种情况下使用的解决方法,但我想知道将来如何处理这个问题,以防我处于必须使用的情况QueryableExtensions
并且需要做类似的事情。