日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

EFCore2.0@Xamarin.Forms

發(fā)布時間:2023/12/4 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 EFCore2.0@Xamarin.Forms 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?? ? 由于忙于Xamarin的書的創(chuàng)作很久沒有和大家見面了,回到博客我會陸續(xù)更新一些最新的Xamarin技術(shù),還有最近一直在努力的人工智能相關(guān)知識。話說csdn的博客改版了??傆X得變化是好事情啊。
? ? ? 這篇博客,我想和大家說說EFCore,在.NET社區(qū),EntityFramework對持久化有很深遠的影響,特別是O/RM節(jié)省了一堆的數(shù)據(jù)庫訪問代碼。到了.NET Core的年代,EF也升級到EntityFrameworkCore. 微軟視EFCore為一個跨平臺,輕量級,可擴展的數(shù)據(jù)庫操作技術(shù)。當(dāng)然我更喜歡用Dapper, 但EFCore對于移動化的數(shù)據(jù)操作場景是非常合適的。這也是我今天的重點。
? ? ??
? ? ? 這里得提提移動端數(shù)據(jù)持久化,在移動端有很多方式,如CoreData, SQLite,還有第三方的大名鼎鼎的Realm(雖然很cool,但我總覺得有點復(fù)雜,因人而異了)。在Xamarin中用EFCore是有先天優(yōu)勢的,特別是在支持.NET Standard項目中。如果你的項目采用SQLite作為你數(shù)據(jù)持久化的一部分,EFCore會是你的最佳搭檔。如果你希望的是其他持久化方案,那個人還是說一句不太合適。
? ? ?如果你想為原有的項目添加EFCore方案,你需要把你的PCL遷移到.NET Standard上,如果是新項目就直接選用.NET Standard上算了。這里吐槽下Visual Studio團隊,Windows下已經(jīng)有Xamarin的.NET Standard模版(左圖),但macOS下是沒有的(右圖)。(Build快到了,你就能不能給我一個統(tǒng)一的呢?還有別告訴我在Beta,大家需要的是Stable)如果你希望在macOS下創(chuàng)建.NET Standard的Xamarin項目,建議你去裝一個Prism模版,或者在Windows下創(chuàng)建好扔過去,還有自己創(chuàng)建.NET Standard Library替換PCL。
? ? ??? ??
? ? ?創(chuàng)建好后,在.NET Standard下添加Nuget庫Microsoft.EntityFrameworkCore.Sqlite。添加成功后剩下的事就是做Model和DbContext.
CourseInfo.cs

? ? public class CourseInfo

? ? {

? ? ? ? [Key]

? ? ? ? public int courseID { get; set; }

? ? ? ? public string courseName { get; set; }


? ? ? ? public List<CourseSession> sessionList { get; set; }

? ? }

CourseSession.cs

? ? public class CourseSession

? ? {

? ? ? ? [Key]

? ? ? ? public int sessionID { get; set; }


? ? ? ? public string sessionName { get; set; }


? ? ? ? public int courseID { get; set; }


? ? ? ? public CourseInfo course { get; set; }

? ? }

CourseDbContext.cs

? ? public class CourseDbContext : DbContext

? ? {

? ? ? ? public DbSet<CourseInfo> Courses { get; set; }

? ? ? ? public DbSet<CourseSession> Sessions { get; set; }


? ? ? ? private string DatabasePath { get; set; }


? ? ? ? public CourseDbContext()

? ? ? ? {


? ? ? ? }


? ? ? ? public CourseDbContext(string databasePath)

? ? ? ? {

? ? ? ? ? ? DatabasePath = databasePath;

? ? ? ? }


? ? ? ? protected override void OnModelCreating(ModelBuilder modelBuilder)

? ? ? ? {

? ? ? ? ? ? modelBuilder.Entity<CourseSession>()

? ? ? ? ? ? ? ? ? ? ? ? .HasOne(p => p.course)

? ? ? ? ? ? ? ? ? ? ? ? .WithMany(b => b.sessionList)

? ? ? ? ? ? ? ? ? ? ? ? .HasForeignKey("courseID");

? ? ? ? }

? ? ? ? protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)

? ? ? ? {

? ? ? ? ? ? optionsBuilder.UseSqlite($"Filename={DatabasePath}");

? ? ? ? }

? ? }

?? ? 這里讓我解釋一下,上面很簡單就是創(chuàng)建兩個表一個是課程CourseInfo,一個是課程內(nèi)容CourseSession,我做了一個1:n的關(guān)聯(lián),數(shù)據(jù)源就是CourseDbContext.?

? ? ? 在MainPage.cs要做的事就是把數(shù)據(jù)庫初始化好,和初始化一些數(shù)據(jù)。

? ? ? ? ? ? ? ?try

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? using (var db = new CourseDbContext(path))

? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? //db.Database.OpenConnection();

? ? ? ? ? ? ? ? ? ? ? ? await db.Database.MigrateAsync();

? ? ? ? ? ? ? ? ? ? ? ? CourseInfo info1 = new CourseInfo() { courseID = 1000, courseName = "Xamarin in action" };

? ? ? ? ? ? ? ? ? ? ? ? CourseInfo info2 = new CourseInfo() { courseID = 1001, courseName = "Azure" };


? ? ? ? ? ? ? ? ? ? ? ? List<CourseInfo> courseList = new List<CourseInfo>() { info1, info2 };


? ? ? ? ? ? ? ? ? ? ? ? if (await db.Courses.CountAsync() < 2)

? ? ? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? ? ? await db.Courses.AddRangeAsync(courseList);

? ? ? ? ? ? ? ? ? ? ? ? ? ? await db.SaveChangesAsync();

? ? ? ? ? ? ? ? ? ? ? ? }


? ? ? ? ? ? ? ? ? ? ? ? CourseSession session1 = new CourseSession() { sessionID = 1, sessionName = "1. What's Xamarin", courseID = 1000 };

? ? ? ? ? ? ? ? ? ? ? ? CourseSession session2 = new CourseSession() { sessionID = 2, sessionName = "1. What's azure", courseID = 1001 };

? ? ? ? ? ? ? ? ? ? ? ? CourseSession session3 = new CourseSession() { sessionID = 3, sessionName = "2. Xamarin Installation", courseID = 1000 };



? ? ? ? ? ? ? ? ? ? ? ? List<CourseSession> sessionList = new List<CourseSession>() { session1, session2,session3 };



? ? ? ? ? ? ? ? ? ? ? ? if (await db.Sessions.CountAsync() < 3)

? ? ? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? ? ? await db.Sessions.AddRangeAsync(sessionList);

? ? ? ? ? ? ? ? ? ? ? ? ? ? await db.SaveChangesAsync();

? ? ? ? ? ? ? ? ? ? ? ? }


? ? ? ? ? ? ? ? ? ? ? ? var list = await db.Sessions.ToListAsync();


? ? ? ? ? ? ? ? ? ? var session = list.Where(item => item.courseID == 1000);

? ? ? ? ? ? ? ? ? ? ObservableCollection<SessionView> viewList = new ObservableCollection<SessionView>();


? ? ? ? ? ? ? ? ? ? foreach (var item in session)

? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? viewList.Add(new SessionView { SessionName = item.sessionName });

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? SessionListView.ItemsSource = viewList;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? catch (Exception ex)

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? var temp = ex.ToString();

? ? ? ? ? ? ? ? }

?? ? 這樣通過EFCore的代碼就完成了,但別忘記在iOS/Android/UWP對SQLite進行初始化,否則你是不能使用SQLite的。方法如下,在每個平臺上添加SQLitePCL,

? ? ? ?iOS在AppDelegate.cs的FinishedLauching方法上添加

?SQLitePCL.raw.SetProvider(new SQLitePCL.SQLite3Provider_sqlite3());
? ?Android在MainActivity.cs上增加

? ? ? ? [DllImport("libsqlite.so")]

? ? ? ? internal static extern int sqlite3_shutdown();


? ? ? ? [DllImport("libsqlite.so")]

? ? ? ? internal static extern int sqlite3_initialize();

? ? ??

?并在OnCreate方法上添加

? ? ? ? sqlite3_shutdown();

? ? ? ? SQLitePCL.raw.SetProvider(new SQLitePCL.SQLite3Provider_e_sqlite3());

? ? ? ? sqlite3_initialize();

?UWP呢?哈哈在Surface Phone出生前,我不會再去考慮了(希望真的有)
? ? ? ?這個時候應(yīng)該可以編譯了吧?如果直接運行會出現(xiàn)以下錯誤:
? ? ? ?Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 1:
? ? ? ?原因是項目缺少了Migrations對數(shù)據(jù)庫結(jié)構(gòu)進行初始化。你需要做一個Migration, 個人建議你創(chuàng)建一個.NET Core Console Application去完成。這樣省事,又方便。創(chuàng)建好一個.NET Core Console Application后先添加Microsoft.EntityFrameworkCore.Design和Microsoft.EntityFrameworkCore.Sqlite, 之后去修改.csproj, 增加ef命令支持

? <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.2" />

? ? ? ?保存好后把之前創(chuàng)建的CourseInfo,CourseSession,CourseDbContext添加進來,restore和rebuild后,去命令行做?

?如果成功就可以生成一個Migrations文件夾,把這個文件夾拷貝進Xamarin.Forms .NET Standard的項目中。再重新運行就可以成功了。
? ? ? ?? ??
? ? ? EFCore + Xamarin.Forms就大功告成了,但我這里得提一個坑,在編譯Android項目時,不知道為啥就是不能部署到機器里面,我找了又找,需要做在Android的csproj上設(shè)置以下,添加如下:

<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.3.0" />

<PropertyGroup>

? <NoWarn>$(NoWarn);NU1605</NoWarn>

</PropertyGroup>

應(yīng)該是Xamarin.Android對.NET Standard兼容未做得太好,但通過這個方法可以避免相關(guān)錯誤。當(dāng)然這個不影響部署發(fā)布了,錯誤我已經(jīng)反饋給微軟那邊了,希望在新的版本中盡快修正。
? ? ? 完整代碼https://github.com/lokinfey/EFCore-Xamarin.Forms
? ? ? EFCore是.NET Core下非常重要的一部分,對于移動端數(shù)據(jù)持久化也有非常重要的意義,我更寄望有更多的功能可以實現(xiàn),或者如第三方的Realm能盡快對EFCore進行支持。


原文:https://blog.csdn.net/kinfey/article/details/80147341


.NET社區(qū)新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com


總結(jié)

以上是生活随笔為你收集整理的EFCore2.0@Xamarin.Forms的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。