使用 LINQ 和 Lambda 加入/Where

发布于 2024-08-31 10:48:24 字数 358 浏览 5 评论 0原文

我在使用 LINQ 和 Lambda 编写的查询时遇到问题。到目前为止,我遇到了很多错误,这是我的代码:

int id = 1;
var query = database.Posts.Join(
    database.Post_Metas,
    post => database.Posts.Where(x => x.ID == id),
    meta => database.Post_Metas.Where(x => x.Post_ID == id),
    (post, meta) => new { Post = post, Meta = meta }
);

我不确定这个查询是否正确。

I'm having trouble with a query written in LINQ and Lambda. So far, I'm getting a lot of errors here's my code:

int id = 1;
var query = database.Posts.Join(
    database.Post_Metas,
    post => database.Posts.Where(x => x.ID == id),
    meta => database.Post_Metas.Where(x => x.Post_ID == id),
    (post, meta) => new { Post = post, Meta = meta }
);

I'm not sure if this query is correct.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

泪冰清 2024-09-07 10:48:24

我发现,如果您熟悉 SQL 语法,那么使用 LINQ 查询语法会更清晰、更自然,并且更容易发现错误:

var id = 1;
var query =
   from post in database.Posts
   join meta in database.Post_Metas on post.ID equals meta.Post_ID
   where post.ID == id
   select new { Post = post, Meta = meta };

但如果您确实坚持使用 lambda,那么您的语法就有点偏离了。这是使用 LINQ 扩展方法的相同查询:

var id = 1;
var query = database.Posts    // your starting point - table in the "from" statement
   .Join(database.Post_Metas, // the source table of the inner join
      post => post.ID,        // Select the primary key (the first part of the "on" clause in an sql "join" statement)
      meta => meta.Post_ID,   // Select the foreign key (the second part of the "on" clause)
      (post, meta) => new { Post = post, Meta = meta }) // selection
   .Where(postAndMeta => postAndMeta.Post.ID == id);    // where statement

I find that if you're familiar with SQL syntax, using the LINQ query syntax is much clearer, more natural, and makes it easier to spot errors:

var id = 1;
var query =
   from post in database.Posts
   join meta in database.Post_Metas on post.ID equals meta.Post_ID
   where post.ID == id
   select new { Post = post, Meta = meta };

If you're really stuck on using lambdas though, your syntax is quite a bit off. Here's the same query, using the LINQ extension methods:

var id = 1;
var query = database.Posts    // your starting point - table in the "from" statement
   .Join(database.Post_Metas, // the source table of the inner join
      post => post.ID,        // Select the primary key (the first part of the "on" clause in an sql "join" statement)
      meta => meta.Post_ID,   // Select the foreign key (the second part of the "on" clause)
      (post, meta) => new { Post = post, Meta = meta }) // selection
   .Where(postAndMeta => postAndMeta.Post.ID == id);    // where statement
倾`听者〃 2024-09-07 10:48:24

你可以采取两种方式。使用 LINQPad (如果您是 LINQ 新手,这非常有用)和虚拟数据库,我构建了以下查询:

Posts.Join(
    Post_metas,
    post => post.Post_id,
    meta => meta.Post_id,
    (post, meta) => new { Post = post, Meta = meta }
)

from p in Posts
join pm in Post_metas on p.Post_id equals pm.Post_id
select new { Post = p, Meta = pm }

在这种特殊情况下,我认为 LINQ 语法更清晰(我根据哪个最容易阅读而在两者之间进行更改)。

我想指出的是,如果您的数据库中有适当的外键(在 post 和 post_meta 之间),那么您可能不需要显式连接,除非您尝试加载大量记录。您的示例似乎表明您正在尝试加载单个帖子及其元数据。假设每个帖子都有很多 post_meta 记录,那么您可以执行以下操作:

var post = Posts.Single(p => p.ID == 1);
var metas = post.Post_metas.ToList();

如果您想避免 n+1 问题,那么您可以显式告诉 LINQ to SQL 一次性加载所有相关项(尽管这当您更熟悉 L2S 时可能是一个高级主题)。下面的示例表示“当您加载帖子时,还通过‘Post_metas’属性表示的外键加载与其关联的所有记录”:

var dataLoadOptions = new DataLoadOptions();
dataLoadOptions.LoadWith<Post>(p => p.Post_metas);

var dataContext = new MyDataContext();
dataContext.LoadOptions = dataLoadOptions;

var post = Posts.Single(p => p.ID == 1); // Post_metas loaded automagically

可以对一个帖子进行多次 LoadWith 调用同一类型或许多不同类型的一组DataLoadOptions。如果您经常这样做,您可能只想考虑缓存。

You could go two ways with this. Using LINQPad (invaluable if you're new to LINQ) and a dummy database, I built the following queries:

Posts.Join(
    Post_metas,
    post => post.Post_id,
    meta => meta.Post_id,
    (post, meta) => new { Post = post, Meta = meta }
)

or

from p in Posts
join pm in Post_metas on p.Post_id equals pm.Post_id
select new { Post = p, Meta = pm }

In this particular case, I think the LINQ syntax is cleaner (I change between the two depending upon which is easiest to read).

The thing I'd like to point out though is that if you have appropriate foreign keys in your database, (between post and post_meta) then you probably don't need an explicit join unless you're trying to load a large number of records. Your example seems to indicate that you are trying to load a single post and its metadata. Assuming that there are many post_meta records for each post, then you could do the following:

var post = Posts.Single(p => p.ID == 1);
var metas = post.Post_metas.ToList();

If you want to avoid the n+1 problem, then you can explicitly tell LINQ to SQL to load all of the related items in one go (although this may be an advanced topic for when you're more familiar with L2S). The example below says "when you load a Post, also load all of its records associated with it via the foreign key represented by the 'Post_metas' property":

var dataLoadOptions = new DataLoadOptions();
dataLoadOptions.LoadWith<Post>(p => p.Post_metas);

var dataContext = new MyDataContext();
dataContext.LoadOptions = dataLoadOptions;

var post = Posts.Single(p => p.ID == 1); // Post_metas loaded automagically

It is possible to make many LoadWith calls on a single set of DataLoadOptions for the same type, or many different types. If you do this lots though, you might just want to consider caching.

酒几许 2024-09-07 10:48:24

Daniel 对语法关系有很好的解释,但我为我的团队整理了这份文档,以便让他们更容易理解。希望这对某人有帮助“在此处输入图像描述"

Daniel has a good explanation of the syntax relationships, but I put this document together for my team in order to make it a little simpler for them to understand. Hope this helps someoneenter image description here

赢得她心 2024-09-07 10:48:24

您的按键选择器不正确。他们应该获取相关表类型的对象并返回要在联接中使用的键。我认为你的意思是这样的:

var query = database.Posts.Join(database.Post_Metas,
                                post => post.ID,
                                meta => meta.Post_ID,
                                (post, meta) => new { Post = post, Meta = meta });

你可以在之后应用 where 子句,而不是作为键选择器的一部分。

Your key selectors are incorrect. They should take an object of the type of the table in question and return the key to use in the join. I think you mean this:

var query = database.Posts.Join(database.Post_Metas,
                                post => post.ID,
                                meta => meta.Post_ID,
                                (post, meta) => new { Post = post, Meta = meta });

You can apply the where clause afterwards, not as part of the key selector.

旧伤还要旧人安 2024-09-07 10:48:24

发帖是因为当我开始LINQ + EntityFramework时,我盯着这些例子看了一天。

如果您使用 EntityFramework,并且在 Post 模型对象上设置了一个名为 Meta 的导航属性,那么这非常简单。如果您正在使用实体并且没有该导航属性,那么您还在等什么?

database
  .Posts
  .Where(post => post.ID == id)
  .Select(post => new { post, post.Meta });

如果您首先编写代码,则可以这样设置该属性:

class Post {
  [Key]
  public int ID {get; set}
  public int MetaID { get; set; }
  public virtual Meta Meta {get; set;}
}

Posting because when I started LINQ + EntityFramework, I stared at these examples for a day.

If you are using EntityFramework, and you have a navigation property named Meta on your Post model object set up, this is dirt easy. If you're using entity and don't have that navigation property, what are you waiting for?

database
  .Posts
  .Where(post => post.ID == id)
  .Select(post => new { post, post.Meta });

If you're doing code first, you'd set up the property thusly:

class Post {
  [Key]
  public int ID {get; set}
  public int MetaID { get; set; }
  public virtual Meta Meta {get; set;}
}
栀子花开つ 2024-09-07 10:48:24

我做过这样的事;

var certificationClass = _db.INDIVIDUALLICENSEs
    .Join(_db.INDLICENSECLAsses,
        IL => IL.LICENSE_CLASS,
        ILC => ILC.NAME,
        (IL, ILC) => new { INDIVIDUALLICENSE = IL, INDLICENSECLAsse = ILC })
    .Where(o => 
        o.INDIVIDUALLICENSE.GLOBALENTITYID == "ABC" &&
        o.INDIVIDUALLICENSE.LICENSE_TYPE == "ABC")
    .Select(t => new
        {
            value = t.PSP_INDLICENSECLAsse.ID,
            name = t.PSP_INDIVIDUALLICENSE.LICENSE_CLASS,                
        })
    .OrderBy(x => x.name);

I've done something like this;

var certificationClass = _db.INDIVIDUALLICENSEs
    .Join(_db.INDLICENSECLAsses,
        IL => IL.LICENSE_CLASS,
        ILC => ILC.NAME,
        (IL, ILC) => new { INDIVIDUALLICENSE = IL, INDLICENSECLAsse = ILC })
    .Where(o => 
        o.INDIVIDUALLICENSE.GLOBALENTITYID == "ABC" &&
        o.INDIVIDUALLICENSE.LICENSE_TYPE == "ABC")
    .Select(t => new
        {
            value = t.PSP_INDLICENSECLAsse.ID,
            name = t.PSP_INDIVIDUALLICENSE.LICENSE_CLASS,                
        })
    .OrderBy(x => x.name);
吻风 2024-09-07 10:48:24

LINQ Join

var productOrderQuery = from product in Product.Setup()//outer sequence
                        join order in OrderDetails.Setup()//inner sequence
                        on product.Id equals order.ProductId //key selector
                        select new//result selector
                        {
                            OrderId = order.Id,
                            ProductId = product.Id,
                            PurchaseDate = order.PurchaseDate,
                            ProductName = product.Name,
                            ProductPrice = product.Price
                        };

方法的查询语法 LINQ Join 的查询语法

var productOrderMethod = Product.Setup().//outer sequence
    Join(OrderDetails.Setup(), //inner sequence
    product => product.Id//key selector
    ,order=> order.ProductId //key selector
    ,(product,order)=> //projection result
        new
        {
            OrderId = order.Id,
            ProductId = product.Id,
            PurchaseDate = order.PurchaseDate,
            ProductName = product.Name,
            ProductPrice = product.Price
        }
    );

Product.cs 供参考

class Product
{
    public int Id { get; set; }
    public string Name { get; set; }

    public decimal Price { get; set; }
    public static IEnumerable<Product> Setup()
    {
        return new List<Product>()
        {
            new Product(){Id=1, Name="Bike", Price=30.33M },
            new Product(){Id=2, Name="Car", Price=50.33M },
            new Product(){Id=3, Name="Bus", Price=60.33M }
        };
    }
}

OrderDetails.cs 类供参考

class OrderDetails
{
    public int Id { get; set; }
    public virtual int ProductId { get; set; }

    public DateTime PurchaseDate { get; set; }
    public static IEnumerable<OrderDetails> Setup()
    {
        return new List<OrderDetails>()
        {
            new OrderDetails(){Id=1, ProductId=1, PurchaseDate= DateTime.Now },
            new OrderDetails(){Id=2, ProductId=1, PurchaseDate=DateTime.Now.AddDays(-1) },
            new OrderDetails(){Id=3, ProductId=2, PurchaseDate=DateTime.Now.AddDays(-2) }
        };
    }

}

Query Syntax for LINQ Join

var productOrderQuery = from product in Product.Setup()//outer sequence
                        join order in OrderDetails.Setup()//inner sequence
                        on product.Id equals order.ProductId //key selector
                        select new//result selector
                        {
                            OrderId = order.Id,
                            ProductId = product.Id,
                            PurchaseDate = order.PurchaseDate,
                            ProductName = product.Name,
                            ProductPrice = product.Price
                        };

Method Syntax for LINQ Join

var productOrderMethod = Product.Setup().//outer sequence
    Join(OrderDetails.Setup(), //inner sequence
    product => product.Id//key selector
    ,order=> order.ProductId //key selector
    ,(product,order)=> //projection result
        new
        {
            OrderId = order.Id,
            ProductId = product.Id,
            PurchaseDate = order.PurchaseDate,
            ProductName = product.Name,
            ProductPrice = product.Price
        }
    );

Product.cs for reference

class Product
{
    public int Id { get; set; }
    public string Name { get; set; }

    public decimal Price { get; set; }
    public static IEnumerable<Product> Setup()
    {
        return new List<Product>()
        {
            new Product(){Id=1, Name="Bike", Price=30.33M },
            new Product(){Id=2, Name="Car", Price=50.33M },
            new Product(){Id=3, Name="Bus", Price=60.33M }
        };
    }
}

OrderDetails.cs class for reference

class OrderDetails
{
    public int Id { get; set; }
    public virtual int ProductId { get; set; }

    public DateTime PurchaseDate { get; set; }
    public static IEnumerable<OrderDetails> Setup()
    {
        return new List<OrderDetails>()
        {
            new OrderDetails(){Id=1, ProductId=1, PurchaseDate= DateTime.Now },
            new OrderDetails(){Id=2, ProductId=1, PurchaseDate=DateTime.Now.AddDays(-1) },
            new OrderDetails(){Id=3, ProductId=2, PurchaseDate=DateTime.Now.AddDays(-2) }
        };
    }

}
千年*琉璃梦 2024-09-07 10:48:24

它可能是这样的

var myvar = from a in context.MyEntity
            join b in context.MyEntity2 on a.key equals b.key
            select new { prop1 = a.prop1, prop2= b.prop1};

It could be something like

var myvar = from a in context.MyEntity
            join b in context.MyEntity2 on a.key equals b.key
            select new { prop1 = a.prop1, prop2= b.prop1};
梦过后 2024-09-07 10:48:24

这个 linq 查询应该适合你。它将获取所有具有帖子元的帖子。

var query = database.Posts.Join(database.Post_Metas,
                                post => post.postId, // Primary Key
                                meta => meat.postId, // Foreign Key
                                (post, meta) => new { Post = post, Meta = meta });

等效 SQL 查询

Select * FROM Posts P
INNER JOIN Post_Metas pm ON pm.postId=p.postId

This linq query Should work for you. It will get all the posts that have post meta.

var query = database.Posts.Join(database.Post_Metas,
                                post => post.postId, // Primary Key
                                meta => meat.postId, // Foreign Key
                                (post, meta) => new { Post = post, Meta = meta });

Equivalent SQL Query

Select * FROM Posts P
INNER JOIN Post_Metas pm ON pm.postId=p.postId
爱给你人给你 2024-09-07 10:48:24

1 等于 1 两个不同的表连接

var query = from post in database.Posts
            join meta in database.Post_Metas on 1 equals 1
            where post.ID == id
            select new { Post = post, Meta = meta };

1 equals 1 two different table join

var query = from post in database.Posts
            join meta in database.Post_Metas on 1 equals 1
            where post.ID == id
            select new { Post = post, Meta = meta };
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文