2014-10-30 49 views
0

我不找任何一个解决的称号,我寻求建议纯属提到的问题,因为我有固定的我自己但我想得到一些专家的意见,我有一个方法,加载用户的详细信息并返回UserProfile()类实体或复杂类型“WebServices.UserProfile”不能在LINQ构建以查询实体

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

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所以最好我想正确地使用它。

谢谢

回答

0

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

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

你可以先做.Where(...)然后.FirstOrDefault(),但你可以在通话中添加,其中标准来.FirstOrDefault(...)

如果你不想选择UserProfile类的所有列,那么您应该创建用于该目的的独立的数据holder类。但是你不能在你的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(); 
    } 
} 

但是,这第二个版本基本上与您的一个版本相同。

+0

好吧,我想我会扩展到只返回我需要的7个字段,因为我并不需要UserProfile中的所有15列,并且从我教过的内容中只选择需要帮助的性能列。 – 2014-10-30 10:49:29

+0

作为一般指导原则,只有选择你需要的东西。但是如果你从表中选择一行,我认为你获得的表现相当不错。另一方面,如果你用这个查询方法调用数百万次... – Maarten 2014-10-30 10:51:00

+0

这就是我想要解决的问题,因为我可以让5000多个用户打这个应用程序,所以我非常理想并试图实现一个合适的方法,因为我想要的最后一件事是应用程序停下来。 – 2014-10-30 10:57:19

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); 
    } 
} 

这将大致做你的代码在做什么。如果没有匹配主键,您可能需要执行一些检查/错误处理。

+0

所以你个人认为你会说你给出的代码示例会更好,即从性能的角度来看?我会添加一些错误,尽管 – 2014-10-30 10:33:37

+0

也来自我个人的经验,我不想从UserProfile表中选择所有的东西,因为我只需要当前有问题的7列,而UserProfile表有大约15个coloumns @ AlexC – 2014-10-30 10:46:20

+1

描述那些7列和15列的成本,看看是否有任何可衡量的差异,我希望看到结果。然后根据您编写的附加代码来衡量维护成本。还要考虑当LoadUserDetails返回的使用UserProfile对象的代码访问您决定使用默认值填充的属性时可能发生的细微错误的代价。 – AlexC 2014-10-30 12:06:17

相关问题