Deelnemen/waar met LINQ en Lambda

Ik heb problemen met een query die is geschreven in LINQ en Lambda. Tot nu toe krijg ik veel fouten, hier is mijn 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 });

Ik ben nieuw in het gebruik van LINQ, dus ik weet niet zeker of deze zoekopdracht correct is.


Antwoord 1, autoriteit 100%

Als je bekend bent met de SQL-syntaxis, merk ik dat het gebruik van de LINQ-querysyntaxis veel duidelijker en natuurlijker is en het gemakkelijker maakt om fouten op te sporen:

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

Als je echter echt vastzit aan het gebruik van lambda’s, is je syntaxis nogal afwijkend. Hier is dezelfde zoekopdracht, met behulp van de LINQ-extensiemethoden:

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

2, Autoriteit 7%

Je zou hiermee twee manieren kunnen gaan. Met behulp van linqpad (van onschatbare waarde als u nieuw bent op LINQ) en een dummy database, heb ik de volgende vragen gebouwd:

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

of

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

In dit specifieke geval denk ik dat de LINQ-syntaxis schoner is (ik verander tussen de twee, afhankelijk van het gemakkelijkst te lezen).

Het ding dat ik wil erop wijzen, is dat als je geschikte buitenlandse sleutels in je database hebt, (tussen post en post_meta), dan heb je waarschijnlijk geen expliciete join nodig, tenzij je een groot aantal probeert te laden Aantal records. Uw voorbeeld lijkt aan te geven dat u probeert een enkele post en zijn metadata te laden. Ervan uitgaande dat er voor elke post veel post_meta-records zijn, kunt u het volgende doen:

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

Als u het N + 1-probleem wilt vermijden, kunt u LINQ aan SQL expliciet vertellen om alle gerelateerde items in één keer te laden (hoewel dit mogelijk een geavanceerd onderwerp is voor wanneer u meer vertrouwd bent met L2S) . Het onderstaande voorbeeld zegt: “Wanneer u een bericht laadt, laadt u ook al haar records die ermee verbonden zijn via de buitenlandse sleutel die wordt weergegeven door het eigenschap ‘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

Het is mogelijk om veel LoadWithte doen, roept u op een enkele set van DataLoadOptionsvoor hetzelfde type of veel verschillende typen. Als je deze loten doet, wil je misschien gewoon caching overwegen.


3, Autoriteit 5%

Daniel heeft een goede uitleg over de syntaxisrelaties, maar ik leg dit document samen voor mijn team om het een beetje eenvoudiger te maken om te begrijpen. Ik hoop dat dit iemand helpt


4, Autoriteit 3%

Uw sleutel selectors zijn onjuist. Ze moeten een object nemen van het type van de betreffende tabel en de sleutel retourneren om in de join te gebruiken. Ik denk dat je dit bedoelt:

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

U kunt de onderstaande clausule achteraf toepassen, niet als onderdeel van de sleutelselector.


Antwoord 5

Ik heb zoiets als dit gedaan;

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

Antwoord 6

Het kan zoiets zijn als

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

Antwoord 7

Deze linq-query zou voor u moeten werken. Het krijgt alle berichten met 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 });

Equivalente SQL-query

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

Antwoord 8

1 is gelijk aan 1 twee verschillende tafelsamen

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

Antwoord 9

Querysyntaxis voor 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
                        };

Methodesyntaxis voor 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 ter referentie

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 klasse ter referentie

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

Other episodes