join tümcesi (C# Başvurusu)
joinYan tümcesi, nesne modelinde doğrudan ilişkisi olmayan farklı kaynak dizilerinden öğeleri ilişkilendirmek için yararlıdır. Tek gereksinim, her kaynaktaki öğelerin eşitlik için karşılaştırılabileceğiniz bazı değerleri paylaşmasına yöneliktir. Örneğin, bir yiyecek dağıtıcısının belirli bir ürünün tedarikçilerinin bir listesi ve alıcıların listesi olabilir. joinYan tümce, örneğin, aynı belirtilen bölgede bulunan ürün sağlayıcılarının ve alıcılarının bir listesini oluşturmak için kullanılabilir.
joinYan tümce iki kaynak dizisini giriş olarak alır. Her dizideki öğelerin, başka bir dizide karşılık gelen bir özellik ile karşılaştırılabileceğiniz bir özellik olması veya bir özelliği içermesi gerekir. joinYan tümcesi, özel anahtar sözcüğünü kullanarak, eşitlik için belirtilen anahtarları karşılaştırır equals . Yan tümce tarafından gerçekleştirilen tüm birleştirmeler join eşlere katılır. Bir yan tümcesinin çıktısının şekli, join gerçekleştirdiğiniz belirli bir JOIN türüne bağlıdır. En yaygın üç JOIN türü aşağıda verilmiştir:
İç birleştirme
Gruba ekleme
Sol dış birleştirme
İç birleştirme
Aşağıdaki örnek bir basit iç Eş birleşim gösterir. Bu sorgu, "ürün adı/kategori" çiftleri için düz bir dizi oluşturur. Aynı kategori dizesi birden çok öğe içinde görüntülenir. Öğesinden bir öğenin categories eşleşmesi yoksa products , bu kategori sonuçlarda görünmez.
var innerJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID
select new { ProductName = prod.Name, Category = category.Name }; //produces flat sequence
Daha fazla bilgi için bkz. İç birleştirmeler gerçekleştirme.
Gruba ekleme
Bir join ifadeye sahip bir yan tümce into , Grup birleşimi olarak adlandırılır.
var innerGroupJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
select new { CategoryName = category.Name, Products = prodGroup };
Bir grup birleşimi, sol kaynak dizisindeki öğeleri sağ taraftaki kaynak dizisinde bir veya daha fazla eşleşen öğeyle ilişkilendiren hiyerarşik bir sonuç sırası üretir. Bir grup katılımı ilişkisel terimlerle eşdeğer değildir; Aslında bir nesne dizileri dizisidir.
Sağ kaynak diziden bir öğe, sol kaynaktaki bir öğeyle eşleşecek şekilde bulunmazsa, join yan tümce bu öğe için boş bir dizi oluşturur. Bu nedenle, sonuç sırasının gruplar halinde düzenlenme dışında, gruba katılması hala temel olarak bir iç eşbirleştirmedir.
Yalnızca bir grup JOIN 'in sonuçlarını seçerseniz, öğelere erişebilirsiniz, ancak eşleştikleri anahtarı tanımlamazsınız. Bu nedenle, önceki örnekte gösterildiği gibi, Grup birleştirmenin sonuçlarının anahtar adı da olan yeni bir türe katılması genellikle daha yararlıdır.
Ayrıca, başka bir alt sorgunun Oluşturucusu olarak bir grup birleşimi sonucunu da kullanabilirsiniz:
var innerGroupJoinQuery2 =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
from prod2 in prodGroup
where prod2.UnitPrice > 2.50M
select prod2;
Daha fazla bilgi için bkz. gruplanmış birleşimler gerçekleştirme.
Sol dış birleştirme
Sol dış birleşimde, hiçbir eşleşen öğe doğru sırada olmasa bile, sol kaynak dizideki tüm öğeler döndürülür. LINQ içinde bir sol dış birleşim gerçekleştirmek için, DefaultIfEmpty bir sol taraftaki öğenin eşleşmesi yoksa, oluşturmak üzere varsayılan bir sağ taraftaki öğe belirtmek için bir grup birleştirimiyle birlikte yöntemi kullanın. nullHerhangi bir başvuru türü için varsayılan değer olarak kullanabilirsiniz veya Kullanıcı tanımlı varsayılan bir tür belirtebilirsiniz. Aşağıdaki örnekte, Kullanıcı tanımlı varsayılan bir tür gösterilir:
var leftOuterJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
from item in prodGroup.DefaultIfEmpty(new Product { Name = String.Empty, CategoryID = 0 })
select new { CatName = category.Name, ProdName = item.Name };
Daha fazla bilgi için bkz. sol dış birleştirmeler gerçekleştirme.
Eşittir işleci
joinYan tümce bir equijoın gerçekleştirir. Diğer bir deyişle, yalnızca iki anahtarın eşitliğine ait eşleşmeleri temel alabilirsiniz. "Büyüktür" veya "Not Equals" gibi diğer karşılaştırma türleri desteklenmez. Tüm birleşimlerin Eş birleşim olduğunu net hale getirmek için join yan tümce equals işleç yerine anahtar sözcüğünü kullanır == . equalsAnahtar sözcüğü yalnızca bir join yan tümcesinde kullanılabilir ve == bazı önemli yollarla işleçten farklı olabilir. Dizeleri karşılaştırırken, equals değere göre karşılaştırmak için bir aşırı yüklemesi vardır ve işleç == başvuru eşitliği kullanır. Karşılaştırmaların her iki tarafında da özdeş dize değişkenleri olduğunda equals ve == aynı sonuca ulaşacak olduğunda: true. Yani, bir program iki veya daha fazla denk dize değişkeni bildirmekle birlikte, derleyici bunların tümünü aynı konumda depoladığında, daha fazla bilgi için bkz. başvuru eşitliği ve dize oluşturma. Diğer önemli fark, null karşılaştırmadır: null equals null equals == true olarak değerlendirilen işleç yerine işleçle false olarak değerlendirilir. Son olarak, kapsam davranışı farklıdır: ile equals sol anahtar, dış kaynak sırasını kullanır ve doğru anahtar, iç kaynağı kullanır. Dış kaynak yalnızca sol taraftaki kapsam içinde yer alır equals ve iç kaynak sırası yalnızca sağ taraftaki kapsamdadır.
Eşit olmayan birleşimler
fromYeni dizileri bir sorguda bağımsız olarak tanıtmak için birden çok yan tümce kullanarak, eşlenmemiş olmayan birleşimler, çapraz birleşimler ve diğer özel birleştirme işlemleri gerçekleştirebilirsiniz. Daha fazla bilgi için bkz. özel JOIN Işlemleri gerçekleştirme.
Nesne koleksiyonlarındaki ve ilişkisel tablolardaki birleşimler
Bir LINQ sorgu ifadesinde, nesne koleksiyonlarında JOIN işlemleri gerçekleştirilir. Nesne koleksiyonları, iki ilişkisel tabloyla tamamen aynı şekilde "birleştirilemez". LINQ içinde açık join yan tümceler yalnızca iki kaynak dizisi herhangi bir ilişkiye bağlı olmadığında gereklidir. İle çalışırken LINQ - SQL , yabancı anahtar tabloları nesne modelinde birincil tablonun özellikleri olarak temsil edilir. Örneğin, Northwind veritabanında, müşteri tablosunun Orders tablosuyla bir yabancı anahtar ilişkisi vardır. Tabloları nesne modeliyle eşlediğinizde, müşteri sınıfının bu müşteriyle ilişkili siparişlerin koleksiyonunu içeren bir Orders özelliği vardır. Aslında, birleşimi sizin için zaten yapıldı.
Bağlamındaki ilgili tablolarda sorgulama hakkında daha fazla bilgi için LINQ - SQL bkz. nasıl yapılır: veritabanı ilişkilerini eşleme.
Bileşik anahtarlar
Bileşik anahtar kullanarak birden çok değerin eşitlik için test edebilirsiniz. Daha fazla bilgi için bkz. bileşik anahtarlar kullanarak ekleme. Bileşik anahtarlar da bir group yan tümcesinde kullanılabilir.
Örnek
Aşağıdaki örnek, aynı eşleşen anahtarları kullanarak bir iç birleşim, bir grup JOIN ve bir sol dış birleşim sonuçlarını aynı veri kaynakları üzerinde karşılaştırır. Bu örneklere bazı ek kodlar, konsol görüntülerindeki sonuçları açıklığa kavuşturacak şekilde eklenir.
class JoinDemonstration
{
#region Data
class Product
{
public string Name { get; set; }
public int CategoryID { get; set; }
}
class Category
{
public string Name { get; set; }
public int ID { get; set; }
}
// Specify the first data source.
List<Category> categories = new List<Category>()
{
new Category {Name="Beverages", ID=001},
new Category {Name="Condiments", ID=002},
new Category {Name="Vegetables", ID=003},
new Category {Name="Grains", ID=004},
new Category {Name="Fruit", ID=005}
};
// Specify the second data source.
List<Product> products = new List<Product>()
{
new Product {Name="Cola", CategoryID=001},
new Product {Name="Tea", CategoryID=001},
new Product {Name="Mustard", CategoryID=002},
new Product {Name="Pickles", CategoryID=002},
new Product {Name="Carrots", CategoryID=003},
new Product {Name="Bok Choy", CategoryID=003},
new Product {Name="Peaches", CategoryID=005},
new Product {Name="Melons", CategoryID=005},
};
#endregion
static void Main(string[] args)
{
JoinDemonstration app = new JoinDemonstration();
app.InnerJoin();
app.GroupJoin();
app.GroupInnerJoin();
app.GroupJoin3();
app.LeftOuterJoin();
app.LeftOuterJoin2();
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
void InnerJoin()
{
// Create the query that selects
// a property from each element.
var innerJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID
select new { Category = category.ID, Product = prod.Name };
Console.WriteLine("InnerJoin:");
// Execute the query. Access results
// with a simple foreach statement.
foreach (var item in innerJoinQuery)
{
Console.WriteLine("{0,-10}{1}", item.Product, item.Category);
}
Console.WriteLine("InnerJoin: {0} items in 1 group.", innerJoinQuery.Count());
Console.WriteLine(System.Environment.NewLine);
}
void GroupJoin()
{
// This is a demonstration query to show the output
// of a "raw" group join. A more typical group join
// is shown in the GroupInnerJoin method.
var groupJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
select prodGroup;
// Store the count of total items (for demonstration only).
int totalItems = 0;
Console.WriteLine("Simple GroupJoin:");
// A nested foreach statement is required to access group items.
foreach (var prodGrouping in groupJoinQuery)
{
Console.WriteLine("Group:");
foreach (var item in prodGrouping)
{
totalItems++;
Console.WriteLine(" {0,-10}{1}", item.Name, item.CategoryID);
}
}
Console.WriteLine("Unshaped GroupJoin: {0} items in {1} unnamed groups", totalItems, groupJoinQuery.Count());
Console.WriteLine(System.Environment.NewLine);
}
void GroupInnerJoin()
{
var groupJoinQuery2 =
from category in categories
orderby category.ID
join prod in products on category.ID equals prod.CategoryID into prodGroup
select new
{
Category = category.Name,
Products = from prod2 in prodGroup
orderby prod2.Name
select prod2
};
//Console.WriteLine("GroupInnerJoin:");
int totalItems = 0;
Console.WriteLine("GroupInnerJoin:");
foreach (var productGroup in groupJoinQuery2)
{
Console.WriteLine(productGroup.Category);
foreach (var prodItem in productGroup.Products)
{
totalItems++;
Console.WriteLine(" {0,-10} {1}", prodItem.Name, prodItem.CategoryID);
}
}
Console.WriteLine("GroupInnerJoin: {0} items in {1} named groups", totalItems, groupJoinQuery2.Count());
Console.WriteLine(System.Environment.NewLine);
}
void GroupJoin3()
{
var groupJoinQuery3 =
from category in categories
join product in products on category.ID equals product.CategoryID into prodGroup
from prod in prodGroup
orderby prod.CategoryID
select new { Category = prod.CategoryID, ProductName = prod.Name };
//Console.WriteLine("GroupInnerJoin:");
int totalItems = 0;
Console.WriteLine("GroupJoin3:");
foreach (var item in groupJoinQuery3)
{
totalItems++;
Console.WriteLine(" {0}:{1}", item.ProductName, item.Category);
}
Console.WriteLine("GroupJoin3: {0} items in 1 group", totalItems);
Console.WriteLine(System.Environment.NewLine);
}
void LeftOuterJoin()
{
// Create the query.
var leftOuterQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
select prodGroup.DefaultIfEmpty(new Product() { Name = "Nothing!", CategoryID = category.ID });
// Store the count of total items (for demonstration only).
int totalItems = 0;
Console.WriteLine("Left Outer Join:");
// A nested foreach statement is required to access group items
foreach (var prodGrouping in leftOuterQuery)
{
Console.WriteLine("Group:");
foreach (var item in prodGrouping)
{
totalItems++;
Console.WriteLine(" {0,-10}{1}", item.Name, item.CategoryID);
}
}
Console.WriteLine("LeftOuterJoin: {0} items in {1} groups", totalItems, leftOuterQuery.Count());
Console.WriteLine(System.Environment.NewLine);
}
void LeftOuterJoin2()
{
// Create the query.
var leftOuterQuery2 =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
from item in prodGroup.DefaultIfEmpty()
select new { Name = item == null ? "Nothing!" : item.Name, CategoryID = category.ID };
Console.WriteLine("LeftOuterJoin2: {0} items in 1 group", leftOuterQuery2.Count());
// Store the count of total items
int totalItems = 0;
Console.WriteLine("Left Outer Join 2:");
// Groups have been flattened.
foreach (var item in leftOuterQuery2)
{
totalItems++;
Console.WriteLine("{0,-10}{1}", item.Name, item.CategoryID);
}
Console.WriteLine("LeftOuterJoin2: {0} items in 1 group", totalItems);
}
}
/*Output:
InnerJoin:
Cola 1
Tea 1
Mustard 2
Pickles 2
Carrots 3
Bok Choy 3
Peaches 5
Melons 5
InnerJoin: 8 items in 1 group.
Unshaped GroupJoin:
Group:
Cola 1
Tea 1
Group:
Mustard 2
Pickles 2
Group:
Carrots 3
Bok Choy 3
Group:
Group:
Peaches 5
Melons 5
Unshaped GroupJoin: 8 items in 5 unnamed groups
GroupInnerJoin:
Beverages
Cola 1
Tea 1
Condiments
Mustard 2
Pickles 2
Vegetables
Bok Choy 3
Carrots 3
Grains
Fruit
Melons 5
Peaches 5
GroupInnerJoin: 8 items in 5 named groups
GroupJoin3:
Cola:1
Tea:1
Mustard:2
Pickles:2
Carrots:3
Bok Choy:3
Peaches:5
Melons:5
GroupJoin3: 8 items in 1 group
Left Outer Join:
Group:
Cola 1
Tea 1
Group:
Mustard 2
Pickles 2
Group:
Carrots 3
Bok Choy 3
Group:
Nothing! 4
Group:
Peaches 5
Melons 5
LeftOuterJoin: 9 items in 5 groups
LeftOuterJoin2: 9 items in 1 group
Left Outer Join 2:
Cola 1
Tea 1
Mustard 2
Pickles 2
Carrots 3
Bok Choy 3
Nothing! 4
Peaches 5
Melons 5
LeftOuterJoin2: 9 items in 1 group
Press any key to exit.
*/
Açıklamalar
joinTarafından izlenen bir yan tümce into bir Join yöntem çağrısına çevrilir. joinTarafından izlenen bir yan tümce into bir GroupJoin yöntem çağrısına çevrilir.
Ayrıca bkz.
- Sorgu anahtar sözcükleri (LINQ)
- Dil ile Tümleşik Sorgu (LINQ)
- Birleştirme İşlemleri
- group tümcesi
- Sol dış birleşimler gerçekleştirme
- İç birleşimler gerçekleştirme
- Gruplanmış birleşimler gerçekleştirme
- Join yan tümcesinin sonuçlarını sıralama
- Bileşik anahtarlar kullanarak birleştirme
- Visual Studio için uyumlu veritabanı sistemleri