使用Database First EF5将查询映射到多个实体,并在DataGrid中查看它们

时间:2013-02-01 17:58:43

标签: c# linq entity-framework entity-framework-5

我正在使用Database First EF5迈出第一步,我正在尝试从EF5中的经典DataTableDataAdapter等中重现我的知识。 ORM范例,但我被困住了:

我习惯使用DataGridsViewsTrees进行大量工作,并使用Stored Procedures填充它们。我用来显示的信息对应多个表/实体。

例如,假设一个博客应用程序。与帖子,用户等如下:

表:

  • Post {Id, Subject, Body, Date, Author}
  • User {Id, Name, Email, Pwd}

为了加入所有表并计算一些值,我们得到StoredProcedure。此SP返回PostUser表中的属性以及2个运行时计算值:

  • Post.Subject, Post.Body, Post.Categories, User.Name, DaysSincePublished, IsAuthorOnline

或者更容易:

  • Post.*, User.*, DaysSincePublished, IsAuthorOnline

问题:

  • 是否可以同时将多个实体中的先前记录集拟合(PostUser)?并用它填充DataGridView?
  • 是否可以将其放入即时创建的实体中?在这种情况下,可以从DataGridView更新(绑定)它。
  • 我是否采取了错误的方法解决问题?

我尝试了Context.ObjectContext.Translate<TEntity>()Context.Database.SqlQuery<TEntity>(storedProcedure, parameterArray);等方法,但只返回1个实体。

注意: 通过此示例,可以忘记StoredProcedure并进行linq查询。但在实际场景中,我有超过10个表的查询和子查询,很少次没有FK,......并且关心服务器性能很多,存储过程是必须的。

1 个答案:

答案 0 :(得分:1)

嗯,无论如何,你的问题很模糊......

为了正确使用ORM,比如EF,我认为理解SQL世界比对象世界更好。

所以,假设您有两个与您的表对应的类:

我想你会首先使用数据库,而不是Code First或Model First。

使用EF时,将从您的数据库生成类。

类似的东西:

public partial class Post {
   public int Id {get;set;}
   public string Subject  {get;set;}
   public string Body {get;set;}
   public DateTime Date {get;set;}
   //etc.
   public virtual User Author {get;set;} //this is what's called a Navigation proeprty, which will help you to find relations with your User class.
}

public partial class User {
   public int Id {get;set;}
   public string Name {get;set;

   public IList<Post> Posts {get;set;}//Navigation property from User to Post class. It's a list, reflecting the one-to-many from Post to User.
}

现在,对于计算属性,您可以通过几种方式执行此操作。

一个是创建分部类Post

的另一部分
public partial class Post {
  public int DaysSincePublished {get {return (DateTime.Now - Date).Days;}}
}

然后,你可以使用这样的简单查询,说你有

public DbSet<User> Users {get;set;}
public DbSet<Post> Posts {get;set;}

然后

var myQuery = context.Users.Include(m => m.Posts);

var list = myQuery.ToList();//this will get data from your db.

在列表中,您已经拥有了所需的所有字段,包括“计算出的属性”(嗯,您已经从Post和User获得了所有字段,实际上可能比您真正需要的更多)。

为避免全部检索,您可以使用匿名类型(或自定义类)中的选择数据

var myQuery = context.Posts.Select(m => new  {
   subject = m.Subject,
   body = m.Body,
   userName = m.User.Name,
   daysSincePublished = SqlFunctions.DiffDays(m.Date, DateTime.Now)//see another way to get calculated value
 });

var list = myQuery.ToList()//retrieving only the required fields from db.

“我的真正需求对于ORM而言过于复杂”的论点并没有那么多意义。无论如何,你仍然可以在需要时使用SP,甚至是原始的sql。目标过于务实,但在得出明确的结论之前要稍微调查一下;)