ASP.NET C# MVC 实体框架
Posted
技术标签:
【中文标题】ASP.NET C# MVC 实体框架【英文标题】:ASP.NET C# MVC Entity Framework 【发布时间】:2020-05-26 22:45:42 【问题描述】:我正在学习 ASP.NET MVC,但我一直坚持使用实体框架创建复杂的 SQL - 它并不复杂,但它可能会变得复杂。
我的常规 ASP.NET C# 网络表单如下所示,我想将其转换为 ASP.NET MVC 并使用 Entity Framework。
string date = Request.QueryString["date"] ?? "";
string strWhere = "";
string sqlTop = "20";
DateTime temp;
if (DateTime.TryParse(date, out temp))
strWhere = "WHERE CAST(NewsDate AS date)='" + temp.ToString("yyyy-MM-dd") + "'";
sqlTop = "50";
using (SqlConnection con = new SqlConnection(WebConfigurationManager.ConnectionStrings["NewsDB"].ConnectionString))
con.Open();
string selectSql = @"SELECT TOP " + sqlTop + @" *
, (SELECT TOP 1 FileName
FROM NewsImage
WHERE NewsGuid = N.NewsGuid
ORDER BY FileOrder ASC) AS FileName
FROM News N " + strWhere + @"
ORDER BY N.NewsDate DESC";
using (SqlCommand selectCmd = new SqlCommand(selectSql, con))
using (SqlDataReader selectDr = selectCmd.ExecuteReader())
while (selectDr.Read())
//My Output logic goes here
我的问题是如何使用实体框架实现这种类型的 SQL。
我已经使用数据库优先的方法创建了实体并设置了DbContext
。
private NewsEntities db = new NewsEntities();
我有两个数据库表:News & NewsImage 单个新闻可以有多个新闻图像(1-N)
我尝试过实现这样的目标:
新闻类
public class NewsClass
public News NewsDetails get; set;
public NewsImage NewsImages get; set;
型号:新闻
public partial class News
public int Id get; set;
public System.Guid NewsGuid get; set;
public string Heading get; set;
public string Text get; set;
public string Author get; set;
public System.DateTime NewsDate get; set;
模型:NewsImage
public partial class NewsImage
public int Id get; set;
public System.Guid NewsGuid get; set;
public string FileName get; set;
public int FileOrder get; set;
控制器:
var newsList = from n in news
join img in newsImages on n.NewsGuid equals img.NewsGuid into table1
from img in table1.DefaultIfEmpty()
select new NewsClass NewsDetails = n, NewsImage = img ;
从这里我被困住了...... 子查询上的“select top 1”,如何实现这个
越来越好... 现在我做了这样的事情:
var newsImages = db.NewsImages.OrderBy(n => n.NewsGuid).OrderBy(n => n.FileOrder).Where(n => n.FileOrder == 10);
var allNews = db.News.OrderByDescending(n => n.NewsDate).Take(sqlTop);
if (validDate)
allNews = allNews.Where(n => n.NewsDate.Year == newsDate.Year && n.NewsDate.Month == newsDate.Month && n.NewsDate.Day == newsDate.Day);
现在我需要将“newsImages”和“allNews”这两个对象合并到一个列表“newsList”中。
如何将查询 allNews 和 newsImages 的两个列表合并到一个列表中,如下所示:
select new NewsList
NewsGuid = n.NewsGuid,
Heading = n.Heading,
FileName = ni.FileName
).Take(sqlTop).ToList<NewsList>();
【问题讨论】:
您是否创建了实体?设置你的 DbContext?这类信息属于问题。 Entity Framework 的全部意义在于您不再需要使用原始 SQL!不要尝试复制这种 1:1 - 使用实体框架方法 - 使用从数据库返回的对象及其导航属性! @marc_s thx,这就是我发布这个的原因,以避免经典的方式进入 EF 方式,但我坚持如何处理这个特定的任务。 查看我的回复 - 可以作为一个起点 - 如果您可以从原始 SQL 中解放出来,您应该会向您展示作为开发人员所获得的好处和巨大的生产力提升 .... EF 的这种方法比我原来的传统方法更快吗? 【参考方案1】:Entity Framework(和其他 ORM)的主要好处是您不必再编写原始 SQL 来实现您的目标。 OR 映射器创建了一个很好用的对象结构,您可以使用它来进行查询。
在你的情况下 - 你会做类似的事情:
string date = Request.QueryString["date"] ?? "";
int sqlTop = 20;
DateTime? newsDate = null;
if (DateTime.TryParse(date, out DateTime temp))
newsDate = temp;
sqlTop = 50;
using (NewsEntities db = new NewsEntities())
// grab the "NewsClass" entries - include the "NewsDetails" and
// "NewsImage" navigation property
var query = db.NewsClass
.Include(n => n.NewsDetails);
.Include(n => n.NewsImage);
// if you have a valid date - use that to refine the query
if (newsDate.HasValue)
query = query.Where(n => n.NewsDetails.NewsDate == newsDate.Value);
// order by NewsDate, and select only "sqlTop" entries
query = query.OrderByDescending(n => n.NewsDetails.NewsDate
.Take(sqlTop);
// now you can iterate over the "News" objects returned from the query
foreach(News n in query)
// get the first image from navigation property
var firstImage = n.NewsImage
.OrderBy(img => img.FileOrder)
.FirstOrDefault();
// do whatever you want with your news - output what you need
【讨论】:
var query = db.News.Include(n => n.NewsImage);这会引发错误。 NewsImage 不是来自 News 表。它来自单独的表 NewsImage,其中有一个名为 NewsGuid 的列,它也将在 News 表中,所以我进行左连接。因为一条新闻会有超过 1 个图像,所以我只抓取第一个作为列表视图。对于详细视图,我将选择所有图像。这就是为什么我有 TOP 1 文件名 我在原来的问题中添加了更多内容......请。检查 btw @marc_s if (DateTime.TryParse(date, out newsDate)) 抛出以下错误:无法从“out System.DateTime?”转换'out System.DateTime' @user2160310:你还没有发布所有相关的细节 - 例如。我不知道NewsDetails
是什么样子的——这些字段是什么以及它们叫什么——所以我不能真正提供100% 准确和正确的实现;但是这篇文章应该给你一个想法和一个起点
.@user2160310:添加了一行代码从导航属性中获取第一个“NewsImage”,按FileOrder
排序
我已经更新了 News 和 NewsImage 类(数据库表 EF 创建了这两个)以上是关于ASP.NET C# MVC 实体框架的主要内容,如果未能解决你的问题,请参考以下文章
使用带有实体框架代码优先和 ASP.NET MVC 3 和 mvc miniprofiler 的 SQL Server CE 时出现问题
表单身份验证、ASP.NET MVC 和 WCF RESTful 服务
MVC Contrib 是不是兑现了提高 ASP.NET MVC 生产力的承诺
在 WPF、Silverlight 和 ASP.NET 之间共享一个公共 DAL