I am using ASP.NET MVC with Entity Framework and I getting my data with SqlQuery like so:
dbBlog.Data.SqlQuery("SELECT bc.id, bc.title, bc.post, bc.date, bc.featuredImage, cc.category FROM BlogClasses bc INNER JOIN CategoriesClasses cc ON bc.category = cc.id WHERE cc.category = '" + id.Replace("_", " ") + "' ORDER BY bc.date desc").ToList();
What I am trying to do now and is an INNER JOIN without using SqlQuery, I have done some reading on Join, I am really struggling to understand it.
I have my categories defined:
private Categories dbCategories = new Categories();
I really have no clue on what the next step it and how .join works, can someone point me in the right direction?
Thanks,
Without knowing your schema I can't give a specific answer, but with Join()
, you need to provide:
IEnumerable<TInner> inner
- This is what you want to Join to .
Expression<Func<TOuter, TKey>> outerKeySelector
- This is how to specify the field from whatever you are joining from .
Expression<Func<TInner, TKey>> innerKeySelector
- This is how you specify the field you are joining to - something from TInner
defined earlier.
Expression<Func<TOuter, TInner, TResult>> resultSelector
- This is what you will be returning from the join.
Example, this SQL Query:
SELECT i.*
FROM Outer o JOIN Inner i ON o.SomeId = i.SomeId
WHERE o.SomeValue < 5
Can be written with Join()
like:
var result = outers.Where(o => o.SomeValue < 5)
.Join(inners, o => o.SomeId, i => i.SomeId, (o, i) => i);
Entity framework uses configurations to reflect relationships between related entities. Given entities like:
public class BlogClass
{
public int Id {get; set;}
public string Title {get; set;}
public string Post {get; set;}
public DateTime Date {get; set;}
public string FeaturedImage {get; set;} // Assuming a URL?
public virtual ClassCategory Category {get;set;}
}
public class ClassCategory
{
public int Id {get; set;}
public string Category {get; set;}
// Other properties...
}
We can set up our configurations:
public class BlogClassConfiguration : EntityTypeConfiguration<BlogClass>
{
public BlogClassConfiguration()
{
ToTable("BlogClasses");
HasKey(x => x.Id)
.Property(x => x.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); // Assuming the ID's are set up as identity or have defaults.
HasRequired(x => x.Category)
.WithMany()
.Map(x => x.MapKey("Category")); // This maps our CategoryClasses reference (Category) to a column on the BlogCategories table called "Category".
}
}
Public class ClassCategoryConfiguration : EntityTypeConfiguration<ClassCategory>
{
public ClassCategoryConfiguration()
{
ToTable("CategoryClasses");
HasKey(x => x.Id)
.Property(x => x.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
}
We tell the DbContext to load these configurations when building its models:
public class BlogDbContext : DbContext
{
public DbSet<BlogClass> BlogClasses {get; set;}
public BlogDbContext(string connectionString)
: base (connectionString)
{}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Configurations.AddFromAssembly(typeof(TestDbContext).Assembly);
}
}
Then EF manages the joins entirely.
var categoryName = category.Replace("_", " ");
using (var context = new BlogContext("BlogConnectionString"))
{
var blogs = context.BlogClasses
.Where(x => x.Category.Category == categoryName)
.OrderByDescending(x => x.Date)
.ToList(); // Assumes not too many items returned!
}
This example scopes a DbContext as an example. Ideally this should be managed by an IoC container and provided as a dependency.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.