iT邦幫忙

0

C# net core entity framework 取得跨表單欄位

各位好,小弟最近在學net core mvc 搭配 entity framework core
如下有2個model 當我使用Query01()時是沒問題的
但如果想得到一個跨表單所組成的表單結果 如Query02
執行結果是跟Query01()一樣 得到所有Subjects欄位,但沒有users.UserName欄位
想請問一下如果想得到跨表單所組成的表單結果,是還要再新增一個對應model嗎?
還是有其他方法可以達成? 謝謝

Subject model:

public class Subject
{
	public int Id { get; set; }
	public string SubjectName { get; set; }
	public int TeacherID { get; set; }
	public int MaxPeople { get; set; }
}

User model:

public class User
{
        public int Id { get; set; }
        public string Account { get; set; }
        public string Password { get; set; }
        public string UserName { get; set; }

}
public List<Subject> Query01()
{
	List<Subject> result = null;      
	using(_DbContext){
		//var query = _DbContext.Subjects; 
		var query = _DbContext.Subjects.FromSqlRaw("select * from subjects");		
		result = query.ToList();       
	}
	return result; 
}

public List<Subject> Query02()
{
	List<Subject> result = null;      
	using(_DbContext){
		var query = _DbContext.Subjects
			.FromSqlRaw("select subjects.*, users.UserName from subjects left join users on subjects.TeacherID = users.Id");
		result = query.ToList();       
	}
	return result; 
}
看更多先前的討論...收起先前的討論...
sion iT邦新手 4 級 ‧ 2019-12-26 10:45:03 檢舉
用_DbContext.Subjects跟_DbContext.User查出來後再用LINQ join
var query1 =_DbContext.Subjects......ToList();
var query2 =_DbContext.User.....ToList();
var result = query1 .join(query2 ,left=>L,right=>R,(L,R)=>new{.....})
米歐 iT邦新手 4 級 ‧ 2019-12-26 11:30:26 檢舉
你用EFCore還用指令查詢?何不用他給你的API就好
xWinter iT邦新手 5 級 ‧ 2019-12-26 15:16:00 檢舉
sion大大 請問一下 照你方法 result 是有得到想要的欄位
那...回傳型別是要如何處理?
sion iT邦新手 4 級 ‧ 2019-12-26 17:50:45 檢舉
應該要再建一個model吧
或是其他大大有更好的方法
xWinter iT邦新手 5 級 ‧ 2019-12-26 18:02:56 檢舉
我也是在想要建新model
但根據需求 應該都會常常跨表單取資料吧
這樣不就要有很多model...
sion iT邦新手 4 級 ‧ 2019-12-26 18:11:15 檢舉
主要還是要看你要應用在甚麼地方吧
你可以public List<Subject> Query01() ,public List<User> Query02();
然後在主程式join,
或是建一個新model,public List<newModel> Query03()

2 個回答

1
fysh711426
iT邦研究生 2 級 ‧ 2019-12-28 22:06:50
最佳解答

使用 導覽屬性 配合 Include 是比較正規的作法

輸出時視情況建立對應的 ViewModel
怕麻煩可以建立一個欄位多一點的 ViewModel 共用

我自己習慣以欄位的重要性區分
例如,給一般使用者看的 ViewModel,欄位就不會包含管理者才能看的資訊,這樣比較不會不小心讓資料外流

Model 部分

public class Subject
{
    public int Id { get; set; }
    public string SubjectName { get; set; }
    public int TeacherID { get; set; }
    public int MaxPeople { get; set; }
    //新增 User 導覽屬性
    public virtual User User { get; set; }
}

DbContext 部分

public class xxxDbContext : DbContext
{
    public xxxDbContext(DbContextOptions<CoreDbContext> options)
        : base(options)
    {
    }

    public DbSet<Subject> Subjects { get; set; }
    public DbSet<User> Users { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Subject>(entity =>
        {
            //設定主索引
            entity.HasKey(p => p.Id);
            //設定關聯性
            entity.HasOne(p => p.User).WithMany()
                .HasForeignKey(p => p.TeacherID);
        });
    }
}

ViewModel 部分

public class SubjectViewModel
{
    public int Id { get; set; }
    public string SubjectName { get; set; }
    public int TeacherID { get; set; }
    public int MaxPeople { get; set; }
    //新增使用者名稱
    public string UserName { get; set; }
}

主程式

public List<SubjectViewModel> Query02()
{
    var result = _DbContext.Subjects.Include(it => it.User).ToList();

    return result.Select(it => new SubjectViewModel
    {
        Id = it.Id,
        SubjectName = it.SubjectName,
        MaxPeople = it.MaxPeople,
        TeacherID = it.TeacherID,
        UserName = it.User?.UserName
    }).ToList();
}

如果不想用 Include 和 ViewModel 可以用純 LINQ 寫法

public object Query02()
{
    var query = from a in _DbContext.Subjects
                join b in _DbContext.Users on a.TeacherID equals b.Id
                select new
                {
                    a.Id,
                    a.SubjectName,
                    a.MaxPeople,
                    a.TeacherID,
                    b.UserName
                };
    return query.ToList();
}

EF 不建議直接寫 SQL,因為 Mapping 的限制很多,使用上會覺得綁手綁腳的

如果喜歡自己下 SQL,我會建議使用 Dapper,會比 EF 靈活很多

xWinter iT邦新手 5 級 ‧ 2019-12-30 11:49:19 檢舉

原來如此,回傳Object型態即可
至於大大提供的方法也會試試看
"欄位多一點的 ViewModel 共用"
這方法貌似不錯
而Dapper這個資料存取套件也會爬文來看看
謝謝回答

fysh711426 iT邦研究生 2 級 ‧ 2019-12-30 12:10:41 檢舉

/images/emoticon/emoticon12.gif

1
米歐
iT邦新手 4 級 ‧ 2019-12-26 11:32:35

我沒這樣用過,但就我EF使用經驗,你應該需要使用Include,Include user這張表試試看,可能可以解決你的問題。

編輯一下,你用EF你的Model就要有關聯,你應該先建立關聯,跟著官方文章做應該就可以
https://docs.microsoft.com/zh-tw/ef/core/modeling/relationships?tabs=fluent-api

xWinter iT邦新手 5 級 ‧ 2019-12-26 15:16:29 檢舉

謝謝 我會再看看這文章內容

我要發表回答

立即登入回答