无法在LINQ to Entities查询中构造实体或复杂类型“Web Services.User Profile”

时间:2014-10-30 10:00:40

标签: c# entity-framework

我不是在找任何人来解决标题中提到的问题我正在寻求建议纯粹是因为我已经修复了我自己,但我想得到一些专家建议,我有一个加载用户的方法详细信息并返回UserProfile()类

如下所示,使用以下代码运行应用程序时的关键点我得到上述错误。

public UserProfile LoadUserDetails(Int64 userId)
    {
        var userProfile = new UserProfile();

        using (var context = new Context())
        {
            userProfile = (from p in context.UserProfile
                           where p.UserId == userId
                           select new UserProfile()
                           {
                               UserId = userId,
                               Firstname = p.Firstname,
                               Surname = p.Surname,
                               Username = p.Username,
                               CurrentlyOnline = p.CurrentlyOnline,
                               JoinedDate = p.JoinedDate,
                               UserLocation = p.UserLocation
                           }).FirstOrDefault();

            context.Dispose();
        }
        return userProfile;
    }

如果我添加.AsEnumerable()它的工作原理如下所示

public UserProfile LoadUserDetails(Int64 userId)
    {
        var userProfile = new UserProfile();

        using (var context = new Context())
        {
            userProfile = (from p in context.UserProfile.AsEnumerable()
                           where p.UserId == userId
                           select new UserProfile()
                           {
                               UserId = userId,
                               Firstname = p.Firstname,
                               Surname = p.Surname,
                               Username = p.Username,
                               CurrentlyOnline = p.CurrentlyOnline,
                               JoinedDate = p.JoinedDate,
                               UserLocation = p.UserLocation
                           }).FirstOrDefault();

            context.Dispose();
        }
        return userProfile;
    }

现在如上所述,我使用以下代码修复了错误,纯粹是因为我阅读的每个解决方案都更倾向于这种方法,我将用户加载到临时类,创建UserProfile()的新实例并填充临时类的相关变量。

public UserProfile LoadUserDetails(Int64 userId)
    {
        var userProfile = new UserProfile();

        using (var context = new Context())
        {
            var t = (from p in context.UserProfile
                     where p.UserId == userId
                     select new
                     {
                         UserId = userId,
                         Firstname = p.Firstname,
                         Surname = p.Surname,
                         Username = p.Username,
                         CurrentlyOnline = p.CurrentlyOnline,
                         JoinedDate = p.JoinedDate,
                         UserLocation = p.UserLocation
                     }).FirstOrDefault();

            userProfile = new UserProfile
            {
                UserId = userId,
                Firstname = t.Firstname,
                Surname = t.Surname,
                Username = t.Username,
                CurrentlyOnline = t.CurrentlyOnline,
                UserLocation = t.UserLocation,
                JoinedDate = t.JoinedDate
            };

            context.Dispose();
        }
        return userProfile;
    }

所以我向你提出的问题是什么是最好的方法代码示例2或3?考虑到表现。

我正在学习实体框架6,所以理想情况下我想正确使用它。

谢谢

2 个答案:

答案 0 :(得分:0)

我认为性能不是问题,但代码非常冗长。我会考虑使用Find function on DbSet来执行以下操作。此代码假设context.UserProfile属于DbSet类型,如果不是这种情况需要能够转换为DbSet并且UserProfile上的UserId属性是实体的密钥。

public UserProfile LoadUserDetails(Int64 userId)
{
    // Assuming context.UserProfile is / can be converted to DbSet<UserProfile>
    // and the userId is the Key to the Entity

    using (var context = new Context())
    {
        return context.UserProfile.Find(userId);
    }
}

这将大致完成您的代码所做的事情。如果没有与主键匹配的话,您可能想要进行一些检查/错误处理。

答案 1 :(得分:0)

您使用.AsEnumerable()走在正确的轨道上。我会这样做:

public UserProfile LoadUserDetails(int userId) {
    using (var context = new Context()) {
        userProfile = context.UserProfile
            .FirstOrDefault(x => x.UserId == userId);
    }
}

您可以先.Where(...)然后.FirstOrDefault(),但您只需在调用.FirstOrDefault(...)时添加where-criteria。

如果您不想选择UserProfile类的所有列,则应为此目的创建单独的数据持有者类。但是您无法在linq查询中使用该类。您的查询将变为类似:

public SmallUserProfile LoadUserDetails(int userId) {
    using (var context = new Context()) {
        userProfile = context.UserProfile
            .Where(x => x.UserId == userId)
            .Select(x => new SmallUserProfile {
                UserId = x.userId,
                // etc...
            })
            .AsEnumerable()
            .Select(x => new SmallUserProfile {
                UserId = x.userId,
                // etc...
            })
            .FirstOrDefault();
    }
}

但是第二个版本与你的某个版本基本相同。