1

我有一个 LINQ 表达式:

        var users = db.Relationships.Where(i => i.RelationshipId== relId)
            .Select(s => s.User).Distinct().Select(s => new UserViewModel() {
            Username = s.Username,
            LastActiveDateTime = s.LastActive, // DateTime, I want it to be a string filtered through my custom GetFriendlyDate method
        }).ToList();

        // convert all DateTimes - yuck!
        foreach (var userViewModel in users) {
            userViewModel.LastActive = DateFriendly.GetFriendlyDate(userViewModel.LastActiveDateTime);
        }

此解决方案有效,但感觉不对

  • 从数据库中获取它们后必须遍历所有users内容,只是为了重新格式化每个属性
  • 在我的 ViewModel 上有一个 DateTime 属性,以便以后可以将其转换为字符串并且再也不会被触及

有什么方法可以GetFriendlyDate直接在查询中使用该方法吗?

4

4 回答 4

2

可能的解决方案,值得一提:

拥有ViewModel 的 getter 属性,它将返回转换后的字符串,例如:

public string LastActive
{
    get
    {
        return DateFriendly.GetFriendlyDate(LastActiveDateTime);        
    }
}

虽然它不能解决您现有 LastActiveDateTime 列的问题,但转换只会在使用时应用(在您看来,很可能 - 无论如何,如果您稍后在查询中尝试使用它,它不会因为您已经知道的原因而工作) ,因此无需手动迭代。

创建 View,它将在服务器端转换数据;所以您的数据已经以您需要的格式返回,如果您使用的是 DBFirst,这可能是最简单和最快的解决方案;

最后,您可以使用 ToList() 两次,一次选择 new ViewModel() 之前(或调用 AsEnumerable(),或找到其他方式来实现查询)。它将从数据库中获取数据,并允许您在 ToList() 之后直接在查询中执行您想要的任何 C# 端函数。但是,如前所述 - 它是关于获取所有符合 ToList() 标准的数据 - 在大多数情况下,这不是合适的解决方案。

这里有一些额外的读物:

如何在 Linq to Entities 查询中调用本地方法?

于 2013-11-09T21:27:57.673 回答
0

我在 LINQpad 中对其进行了测试,并且可以正常工作。它仍然有点迭代用户(使用 LINQ),但您不必将 DateTime 属性添加到您的视图模型类。您也可以使用 Automapper 将用户集合转换为 UserViewModel 对象集合。当然,它仍然会遍历用户,但您不会看到它。

当然必须创建一些设置代码,因为我没有你的数据库。

void Main()
{
        var db = new List<User> { 
            new User { LastActive = DateTime.Now, Username = "Adam", Lastname = "Nowak" },
            new User { LastActive = DateTime.Now.AddYears(1), Username = "Eve", Lastname = "Kowalska"}
        };

        // select only properties that you need from database
        var users = db
            .Select(user => new { Username = user.Username, LastActive = user.LastActive})
            .Distinct()
            .ToList();

        var usersVM = from u in users
        select new UserViewModel { Username = u.Username, LastActiveDateTime = DateFriendly.GetFriendlyDate(u.LastActive)};

        usersVM.Dump();
}

        class User
        {
            public DateTime LastActive;
            public string Username;
            public string Lastname;
        };
        class UserViewModel
        {
            public string Username;
            public string LastActiveDateTime;
        }

        static class DateFriendly
        {
            public static string GetFriendlyDate(DateTime date)        
            {
                return "friendly date " + date.Year;
            }
        }

这输出

用户名 LastActiveDateTime

亚当友好约会 2013

前夕友好约会 2014

于 2013-11-09T21:25:04.563 回答
-1

There is no direct Concert.ToDate method available for LINQ. But you can try using the DateAdd method from the SqlFunctions class:

var users = db.Relationships.Where(i => i.RelationshipId== relId)
    .Select(s => new 
    {
        s.User.Username,
        LastActive=SqlFunctions.DateAdd("d",0, s.LastActive)
    })
    .ToList().Select(s => new UserViewModel()
    {
        Username = s.Username,
        LastActiveDateTime = s.LastActive
    });
于 2013-11-10T09:56:38.103 回答
-2

下面的工作不行吗?

var users = db.Relationships.Where(i => i.RelationshipId== relId)
        .Select(s => s.User).Distinct().Select(s => new UserViewModel() {
        Username = s.Username,
        LastActiveDateTime = DateFriendly.GetFriendlyDate(s.LastActive)        
    }).ToList();
于 2013-11-09T21:11:46.740 回答