سؤال

I have a database with 2 tables: "Albumes" and "Categories".

Each Album has an "id" and a "categoryId" property. although each Category has a "name" property.

I can get the Album.id via QueryString from another page and show the desired Album details in a formview. now i want to show the name of category which contains that album.

I try to do this:

public string GetCategoryName(int albumCategoryId)
{
    var _db = new Trying.Models.AlbumContext();

    IQueryable<Category> query = _db.Categories;
    query = query.Where(c => c.id == albumCategoryId);
    Category ca = new Category();
    //some code
    return ca.name;
}

My problem is in "//some code" section! there, I must convert "IQueryabl query" to "Category ca".

How to do this?

هل كانت مفيدة؟

المحلول

Where returns a set of all matching entities but you only want a single one.

public string GetCategoryName(Int32 albumCategoryId)
{
   using (var _db = new Trying.Models.AlbumContext())
   {
      return _db.Categories.Single(c.id == albumCategoryId).Name;
   }
}

Using Single will throw an exception if there is no matching category and you should use this if you are sure that the category has to exist. If you are not sure whether the category exists or not, you can use SingleOrDefault to get null if there is no matching category. First or FirstOrDefault would work, too, but they are semantically wrong because you don't want the first category, you want to only one. SingleOrDefault obviously requires handling the case that there is no matching category.

public string GetCategoryName(Int32 albumCategoryId)
{
   using (var _db = new Trying.Models.AlbumContext())
   {
       var category = _db.Categories.SingleOrDefault(c.id == albumCategoryId);

       if (category != null)
       {
          return category.Name;
       }
       else
       {
          // Handle the no category found case by returning a default value,
          // throwing an exception or what ever fits your needs.
       }
   }
}

Also note that you should use your database context in an usingstatement to ensure that it gets early and correctly disposed even in the case of an error.

Further you can access the name of the category directly by navigating through your navigation properties.

var categoryName = album.Category.Name;

This is obviously only useful when you have the album object available and you have to ensure that you load the category by either using lazy loading or explicitly including it if you use eager loading.

var album = _db.Albumes.Include(a => a.Category)
                       .Single(a => a.Id = 42);

This will load the album with Id 42 and because of Include(a => a.Category) also the category of this album. Whether this is better or worse than explicitly querying the category name depends of course on your requirements.

نصائح أخرى

Try this:

public string GetCategoryName(int albumCategoryId)
{
    var _db = new Trying.Models.AlbumContext();

    IQueryable<Category> query = _db.Categories;

    Category ca = query.First(c => c.id == albumCategoryId);

    return ca.name;
}

I will explain with some examples, check the type of the variable because thats what each line is going to return:

list<Category> list = query.Where(c => c.id == albumCategoryId).AsEnumerable();
Category category= query.FisrtOrDefault(c => c.id == albumCategoryId);

IQueryable<T> is a collection.

You need to limit your collection to a single item.

query.Where will also result in a collection. I believe you're looking for a unique item by id. I would recommend Single instead:

var ca = query.Single(c => c.id == albumCategoryId);
return ca.name;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top