首页 > 解决方案 > C#实体框架核心如何创建linq查询模板泛型函数

问题描述

我有一个简单的一对多模型:一本书可以有很多书籍类别,代码片段 1/2 - 模型:

    public class Book
{
    public int BookId { get; set; }

    [Required]
    public string Title { get; set; }
    public ICollection<BookCategory> BookCategories { get; set; }
}
public class Category
{
    public int CategoryId { get; set; }
    public string CategoryName { get; set; }

}
public class BookCategory
{
    public int BookId { get; set; }
    public Book Book { get; set; }
    public int CategoryId { get; set; } 
}

Snippet 2/2 - 保存/更新书籍对象和书籍类别映射数据的 MVC 控制器代码

        public async Task<IActionResult> Book(int? id, Book book, List<int> bookCategoryIds)
    {
        id = id ?? 0;
        if (id != book.BookId)      
        {
            return NotFound();
        }

        var category = _context.Categories;
        if (ModelState.IsValid)
        {

            // if create a new book
            if (id == 0)
            {               
                _context.Add(book);

            }
            else    // existing book
            {
                _context.Update(book);

                var bookCategories = await _context.BookCategories.Where(bc => bc.BookId == book.BookId).ToListAsync();

                if (bookCategories != null && bookCategories.Count > 0)
                {
                    _context.BookCategories.RemoveRange(bookCategories);
                }

            }

            if (bookCategoryIds.Count > 0)
            {
                var cats = await _context.Categories.ToListAsync();
                foreach (Category c in cats)
                {
                    if (bookCategoryIds.Contains(c.CategoryId))
                    {
                        _context.BookCategories.Add(new BookCategory() { BookId = book.BookId, CategoryId = c.CategoryId });
                    }
                }

            }

            await _context.SaveChangesAsync();

            return RedirectToAction(nameof(Index));
        }
        return View(book);
    }

我的问题是,应用程序可能需要处理许多此类映射表(BookCaterogies、UserRoles 等)的保存/更新。是否可以为所有此类情况创建模板/通用函数?
例如:

public static Task SaveMappingData<T>(DbContext _context, int id, T object, T lookupTable, T mappingTable  )
{
    var lookup = _context.lookupTable;  

            // if create a new object
            if (id == 0)
            {   // dynamically find the object table
                _context.ObjectTableName.Add(object);

            }
            else    // existing object
            {
                _context.ObjectTableName.Update(object);

                var mappingDataList = await _context.mappingTable.Where(bc => bc.MappingTableId== object.objectId).ToListAsync();

                if (mappingDataList != null && mappingDataList .Count > 0)
                {
                    _context.MappingTable.RemoveRange(mappingDataList );
                }

            }
    //more code ...

}

所以在控制器中我只需要调用函数并传入如下参数:

SaveMappingData(_context, id, book, bookCategoryIds, Categories, BookCategories);

并且该函数能够定位图书对象的数据库表,然后定位Id列并找到图书对象(或其他类的对象),然后使用查找表(Categories)和映射表(BookCategories)来更新值。所以问题归结为如何动态定位对象的数据库表及其主键,然后使用它来组合 linq 查询来执行 CRUD。

谢谢你。

标签: c#linqasp.net-coreentity-framework-core

解决方案


推荐阅读