Almacenamiento En Caché En Entity Framework Core Usando NCache

En este artículo se explicará cómo integrar Entity Framework Core con un motor de almacenamiento en caché usando NCache. El artículo brindará un ejemplo práctico de cómo podríamos configurar nuestro Entity Framework Core en una aplicación de consola y cómo utilizar NCache para realizar solicitudes más rápidas a la base de datos con su caché distribuida en memoria nativa.

¿Qué es Entity Framework Core?

Entity Framework Core es el ORM (Object Relational Mapper) más reciente de Microsoft, que ayuda a las aplicaciones de software a mapear, conectar y administrar entidades en una amplia gama de bases de datos. Entity Framework Core es de código abierto y multiplataforma, siendo el 1 ORM principal utilizado por software que utiliza tecnologías de Microsoft.

Al momento de escribir este artículo, Entity Framework Core ofrece dos formas de conectar sus entidades a la base de datos:

  • Code First, escribiendo primero las entidades de su proyecto y luego reflejando esos objetos en la base de datos;
  • Base de datos Primero, crea primero tu base de datos y luego genera las entidades de tu proyecto.

¿Qué es NCache?

NCache también es un software de código abierto y multiplataforma. Su servidor de caché ofrece una caché distribuida en memoria escalable para .NET, Java, Scala, Python y Node.js. Como este artículo se centrará en las tecnologías .NET, podemos usar NCache para aprovechar los siguientes usos:

  • almacenamiento de estado de sesión ASP.NET;
  • Caché de estado de vista de ASP.NET;
  • Caché de salida ASP.NET;
  • Caché de Entity Framework;
  • Caché de segundo nivel de NHibernate.

NCache con Entity Framework Core

Podemos agregar una capa de caché entre Entity Framework Core y nuestra aplicación con NCache, esto mejoraría el tiempo de respuesta de nuestras consultas y reduciría la necesidad de viajes de ida y vuelta a la base de datos en la medida en que obtendríamos datos de las entidades almacenadas en caché de NCache. 

Opciones de almacenamiento en caché

NCache brinda la posibilidad de tener un conjunto diferente de opciones para enviar desde cada solicitud, lo que significa que podemos usar el caché de manera diferente según el conjunto de resultados con el que estamos trabajando para ser más eficientes.

Como vamos a ver en los ejemplos prácticos, debemos proporcionar las opciones de caché en cada solicitud a NCache y esas opciones son las siguientes:

  • AbsoluteExpirationTime, establece el tiempo absoluto en que caducará el elemento almacenado en caché;
    • Tipo de datos: fecha y hora
  • CreateDbDependency, crea o no una dependencia de base de datos a partir del conjunto de resultados;
    • Tipo de dato: booleano
  • ExpirationType, establece el tipo de vencimiento:
    • Absoluto,
    • Corredizo,
    • Ninguna.
  • IsSyncEnabled, establece si los elementos caducados deben volver a sincronizarse con la base de datos.
    • Tipo de dato: booleano
  • Prioridad, establece la prioridad relativa de los elementos almacenados en la memoria caché.
    • Normal,
    • Bajo,
    • Debajo de lo normal,
    • Por encima de lo normal,
    • Alto,
    • no extraíble,
    • Defecto
  • QueryIdentifier, identificador del conjunto de resultados.
    • Tipo de datos: cadena.
  • ReadThruProvider, establece el proveedor de lectura para la sincronización de caché
    • Tipo de datos: cadena
  • SlidingExpirationTime, establece el tiempo de vencimiento deslizante
    • Tipo de datos: Intervalo de tiempo
  • StoreAs, establece cómo se almacenarán los elementos.
    • Recopilación
    • Entidades separadas

Llamadas diferidas

NCache tiene sus propios métodos de extensión para que podamos trabajar con llamadas diferidas de Entity Framework Core y están en 3 grupos diferentes:

  • Operadores Agregados, realizando operaciones contra cobranzas. Se puede usar con los métodos FromCache y FromCacheOnly .
    • Promedio diferido.
      • Productos.Seleccionar(o => o.PrecioUnitario).PromedioDiferido()
    • Recuento diferido
      • Clientes.Seleccionar(c => c.País).AgruparPor(c => c).Recuento diferido()
    • DiferidoMin
      • Pedidos.Dónde(o => o.CustomerId == "VINET").Select(o => o.RequiredDate).DeferredMin()
    • DiferidoMax
      • Pedidos.Select(o => o.RequiredDate).DeferredMax()
    • Suma diferida
      • OrderDetails.Select(o => o.UnitPrice).DeferredSum()
  • Operadores de elementos, haciendo operaciones para elementos individuales. Solo se puede usar con el método FromCache .
    • DeferredElementAtOrDefault
      • Customers.DeferredElementAtOrDefault(c => c.City == "Londres")
    • DeferredFirst
      • Customers.DeferredFirst(c => c.ContactTitle == "Representante de ventas")
    • DeferredFirstOrDefault
      • Customers.DeferredFirstOrDefault(c => c.ContactTitle == "Representante de ventas")
    • DiferidoÚltimo
      • Clientes.ÚltimoAplazado(c => c.Ciudad == "Londres")
    • DeferredLastOrDefault
      • Customers.DeferredLastOrDefault(c => c.City == "Londres")
    • DiferidoSoltero
      • Clientes.SolteroDiferido(c => c.IdCliente == "ALFKI")
    • DeferredSingleOrDefault
      • Customers.DeferredSingleOrDefault(c => c.CustomerId == "ANATR")
  • Otros. Solo se puede usar con el método FromCache .
    • DiferidoTodo
      • Productos.DeferredAll(expresión)
    • DeferredLongCount
      • Productos.DeferredLongCount()
    • DeferredContains
      • Products.DeferredContains (nuevos productos { ProductId = 1 })

Métodos de almacenamiento en caché

Métodos de NCache para manipular objetos almacenados en caché:

  • Insertar

Inserta un solo objeto en el caché con sus propias opciones. Devuelve la clave de caché

var customerEntity = new Customers
   {
       CustomerId = "HANIH",
       ContactName = "Hanih Moos",
       ContactTitle = "Sales Representative ",
       CompanyName = "Blauer See Delikatessen"
   };

   //Add customer entity to database
   database.Customers.Add(customerEntity);
   database.SaveChanges();

   //Caching options for cache
   var options = new CachingOptions
   {
       QueryIdentifier = "CustomerEntity",
       Priority = Runtime.CacheItemPriority.Default,
   };

   //Add customer entity to cache
   Cache cache = database.GetCache();

   cache.Insert(customerEntity, out string cacheKey, options);
  • Quitar (entidad objeto)

Elimina un solo objeto de la memoria caché.

var cust = new Customers
  {
      CustomerId = "HANIH",
      ContactName = "Hanih Moos",
      ContactTitle = "Sales Representative",
      CompanyName = "Blauer See Delikatessen"
  };

  cache.Remove(cust);
  • Eliminar (cadena cacheKey)

Eliminar un objeto pasando su clave de caché

cache.Remove("cacheKey");
  • RemoveByQueryIdentifier

Eliminar todas las entidades del caché que coincidan con el identificador de consulta

Tag tag = new Tag(queryIdentifier);
cache.RemoveByQueryIdentifier(tag);

Almacenamiento en caché con métodos de extensión NCache 

Métodos de extensión de NCache para Entity Framework Core

  • Obtener Caché

Obtiene la instancia de caché.

using (var context = new NorthwindContext())
{
Cache cache = context.GetCache();
}
  • DesdeCaché

Si hay datos almacenados en caché, se devolverán sin pasar por la fuente de datos. Si no hay datos almacenados en caché, los datos se devolverán desde la fuente de datos y se almacenarán en caché.

var options = new CachingOptions
{
    StoreAs = StoreAs.SeperateEntities
};

var resultSet = (from cust in context.Customers
                 where cust.CustomerId == 10
                 select cust).FromCache(options);

Devolver la cacheKey del conjunto de resultados

var options = new CachingOptions
{
    StoreAs = StoreAs.Collection
};

var resultSet = (from cust in context.Customers
                where cust.CustomerId == 10
                select cust).FromCache(out string cacheKey, options);
  • Cargar en caché

Cada solicitud va primero a la fuente de datos, almacena en caché su conjunto de resultados y lo devuelve.

var options = new CachingOptions
    {
        StoreAs = StoreAs.SeperateEntities
    };

    var resultSet = (from custOrder in context.Orders
                     where custOrder.Customer.CustomerId == 10
                     select custOrder)).LoadIntoCache(options);

Devolver la clave de caché del conjunto de resultados

var options = new CachingOptions
{
    StoreAs = StoreAs.Collection
};

var resultSet = (from custOrder in context.Orders
                 where custOrder.Customer.CustomerId == 10
                 select custOrder)).LoadIntoCache(out string cacheKey, options);
  • DesdeCacheOnly

Nunca va a la fuente de datos. La solicitud solo va a la memoria caché; si no se almacena ningún resultado coincidente, se devolverá como un conjunto de resultados vacío.

Las inclusiones y las uniones no son compatibles con FromCacheOnly().

var resultSet = (from cust in context.Customers
                 where cust.CustomerId == someCustomerId
                 select cust).FromCacheOnly();

Implementación de NCache paso a paso

0. Requisitos previos

1. La aplicación

  • Cree una aplicación de consola C# dirigida a .NET 6.0 e instale los siguientes paquetes nugets:
    • EntityFrameworkCore.NCache
    • Microsoft.EntityFrameworkCore.SqlServer
    • Microsoft.EntityFrameworkCore.SqlServer.Diseño
    • Microsoft.EntityFrameworkCore.Herramientas
    • System.Data.SqlClient
    • System.Collections
  • Los siguientes archivos NCache se insertarán en su proyecto después de instalar los paquetes Nuget.
    • cliente.ncconf
    • config.ncconf
    • tls.ncconf

2. Modelos

Para esta muestra, se creó una relación de modelo muy simple, de la siguiente manera:

  • Producto
[Serializable]
public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public double Price { get; set; }
    public List<Transaction> Transactions { get; set; }
    public Store Store { get; set; }
    public int? StoreId { get; set; }
}
  • Tienda
[Serializable]
public class Store
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Location { get; set; }
    public ICollection<Product> AvailableProducts { get; set; }
    public ICollection<Consumer> RegularConsumers { get; set; }
}
  • Consumidor
[Serializable]
public class Consumer
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Store FavouriteStore { get; set; }
    public int? FavouriteStoreId { get; set; }
    public List<Transaction> Transactions { get; set; }
}
  • Transacción
[Serializable]
public class Transaction
{
     public int Id { get; set; }

     public Consumer Consumer { get; set; }
     public int ConsumerId { get; set; }

     public Product Product { get; set; }
     public int ProductId { get; set; }
}
  • DBContexto

La clase DBContext tiene configuraciones de inicialización de NCache y la relación del modelo.

public class SampleDbContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        // configure cache with SQLServer DependencyType and CacheInitParams
        CacheConnectionOptions initParams = new CacheConnectionOptions();
        initParams.RetryInterval = new TimeSpan(0, 0, 5);
        initParams.ConnectionRetries = 2;
        initParams.ConnectionTimeout = new TimeSpan(0, 0, 5);
        initParams.AppName = "appName";
        initParams.CommandRetries = 2;
        initParams.CommandRetryInterval = new TimeSpan(0, 0, 5);
        initParams.Mode = IsolationLevel.Default;

        NCacheConfiguration.Configure("democache", DependencyType.SqlServer, initParams);

        optionsBuilder.UseSqlServer(@"Data Source=DESKTOP-AT3H2E;Initial Catalog=sampleDatabase;Integrated Security=True");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Store>()
            .HasMany(x => x.AvailableProducts)
            .WithOne(x => x.Store)
            .HasForeignKey(x => x.StoreId)
            .IsRequired(false)
            .OnDelete(DeleteBehavior.NoAction);

        modelBuilder.Entity<Store>()
            .HasMany(x => x.RegularConsumers)
            .WithOne(x => x.FavouriteStore)
            .HasForeignKey(x => x.FavouriteStoreId)
            .IsRequired(false)
            .OnDelete(DeleteBehavior.NoAction);

        modelBuilder.Entity<Transaction>()
            .HasOne(x => x.Consumer)
            .WithMany(x => x.Transactions)
            .HasForeignKey(x => x.ConsumerId)
            .IsRequired(false);

        modelBuilder.Entity<Transaction>()
            .HasOne(x => x.Product)
            .WithMany(x => x.Transactions)
            .HasForeignKey(x => x.ProductId)
            .IsRequired(false);
    }

    public DbSet<Store> Stores { get; set; }
    public DbSet<Consumer> Consumers { get; set; }
    public DbSet<Product> Products { get; set; }
    public DbSet<Transaction> Transactions { get; set; }
}

3. Métodos NCache

Aquí está la clase con los métodos NCache necesarios para manipular objetos desde y hacia el caché.

public class NCacheExtensions
{
    private SampleDbContext Database { get; set; }
    private CachingOptions CachingOptions { get; set; }
    private Cache Cache { get; set; }

    public NCacheExtensions(SampleDbContext database)
    {
        this.Database = database;
        this.CachingOptions = new CachingOptions
        {
            QueryIdentifier = "Sample QueryIdentifier",
            Priority = Alachisoft.NCache.Runtime.CacheItemPriority.Default,
            CreateDbDependency = false,
            StoreAs = StoreAs.Collection
        };

        Cache = database.GetCache();
    }

    public string AddSingleEntity<T>(T entity)
    {
        Cache.Insert(entity, out string cacheKey, this.CachingOptions);
        return cacheKey;
    }
    public void RemoveSingleEntity<T>(T entity)
    {
        Cache.Remove(entity);
    }
    public void RemoveSingleEntity(string cacheKey)
    {
        Cache.Remove(cacheKey);
    }
    public void RemoveByQueryIdentifier(string queryIdentifier)
    {
        var tag = new Tag(queryIdentifier);
        Cache.RemoveByQueryIdentifier(tag);
    }

    public IEnumerable<Consumer> GetAllConsumersFromCache(CachingOptions cachingOptions)
    {
        return Database.Consumers.Include(x => x.Transactions).ThenInclude(x => x.Product).FromCache(cachingOptions);
    }
    public async Task<IEnumerable<Consumer>> GetAllConsumersFromCacheAsync(CachingOptions cachingOptions)
    {
        return await Database.Consumers.Include(x => x.Transactions).ThenInclude(x => x.Product).FromCacheAsync(cachingOptions);
    }
    public IEnumerable<Consumer> LoadAllConsumersIntoCache(CachingOptions cachingOptions)
    {
        return Database.Consumers.Include(x => x.Transactions).ThenInclude(x => x.Product).LoadIntoCache(cachingOptions);
    }
    public async Task<IEnumerable<Consumer>> LoadAllConsumersIntoCacheAsync(CachingOptions cachingOptions)
    {
        return await Database.Consumers.Include(x => x.Transactions).ThenInclude(x => x.Product).LoadIntoCacheAsync(cachingOptions);
    }
    public IEnumerable<Consumer> GetAllConsumersFromCacheOnly(CachingOptions cachingOptions)
    {
        return Database.Consumers.FromCacheOnly();
    }
}

4.La clase program.cs

Aquí tenemos el punto de inicio de nuestra aplicación de consola. Con un ejemplo sobre cómo conectarse a NCache y usar sus métodos de extensión que se proporcionaron anteriormente.

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Hello World!");

        using (var context = new SampleDbContext())
        {
            var cachedContext = new NCacheExtensions(context);

            Console.WriteLine("start LoadAllConsumersIntoCache " + DateTime.Now.ToString("HH:mm:ss.f"));
            var loadInCache = cachedContext.LoadAllConsumersIntoCache(new CachingOptions { StoreAs = StoreAs.Collection, QueryIdentifier = "Sample QueryIdentifier" });
            Console.WriteLine("finish LoadAllConsumersIntoCache" + DateTime.Now.ToString("HH:mm:ss.f"));

            Console.WriteLine("start GetAllConsumersFromCache " + DateTime.Now.ToString("HH:mm:ss.f"));
            var getFromCache = cachedContext.GetAllConsumersFromCache(new CachingOptions { Priority = Alachisoft.NCache.Runtime.CacheItemPriority.Default });
            Console.WriteLine("finish GetAllConsumersFromCache " + DateTime.Now.ToString("HH:mm:ss.f"));

            Console.WriteLine("start load from DBContext " + DateTime.Now.ToString("HH:mm:ss.f"));
            var getFromDb = context.Consumers.Include(x => x.Transactions).ThenInclude(x => x.Product);
            Console.WriteLine("finishg load from DBContext " + DateTime.Now.ToString("HH:mm:ss.f"));

            var cachedEntity = cachedContext.AddSingleEntity<Consumer>(getFromDb.FirstOrDefault());
            Console.WriteLine("cache key: " + cachedEntity);

            cachedContext.RemoveSingleEntity(cachedEntity);
            cachedContext.RemoveByQueryIdentifier("Sample QueryIdentifier");

        }
    }
}

Funcionamiento de la aplicación:

¡Felicidades! Ha utilizado con éxito NCache para almacenar en caché sus datos de Entity Framework Core.

Esta historia se publicó originalmente en https://www.c-sharpcorner.com/article/caching-in-entity-framework-core-using-ncache/ 

#ncache #entity-framework 

Almacenamiento En Caché En Entity Framework Core Usando NCache
坂本  篤司

坂本 篤司

1654967340

NCacheを使用したEntityFrameworkCoreでのキャッシュ

この記事では、NCacheを使用してEntityFrameworkCoreをキャッシングエンジンと統合する方法について説明します。この記事では、コンソールアプリケーションでEntity Framework Coreをセットアップする方法と、NCacheを使用して、ネイティブのメモリ内分散キャッシュを使用してデータベースに対してより高速なリクエストを行う方法の実際的な例を示します。

Entity Framework Coreとは何ですか?

Entity Framework Coreは、Microsoftの最新のORMであるObject Relational Mapperであり、ソフトウェアアプリケーションがエンティティをさまざまなデータベースにマッピング、接続、および管理するのに役立ちます。Entity Framework Coreはオープンソースでクロスプラットフォームであり、Microsoftテクノロジを使用するソフトウェアで使用されるORMのトップ1です。

この記事を書いている時点で、Entity Framework Coreは、エンティティをデータベースに接続する2つの方法を提供しています。

  • コード最初に、プロジェクトのエンティティを最初に記述し、次にそれらのオブジェクトをデータベースに反映します。
  • データベースまず、データベースを最初に作成してから、プロジェクトのエンティティを生成します。

NCacheとは何ですか?

NCacheは、オープンソースおよびクロスプラットフォームのソフトウェアでもあります。そのキャッシュサーバーは、.NET、Java、Scala、Python、およびNode.js用のスケーラブルなメモリ内分散キャッシュを提供します。この記事では.NETテクノロジーに焦点を当てているため、NCacheを使用して次の使用法を利用できます。

  • ASP.NETセッション状態ストレージ。
  • ASP.NETビューステートキャッシング。
  • ASP.NET出力キャッシュ。
  • EntityFrameworkキャッシュ;
  • NHibernateの第2レベルのキャッシュ。

EntityFrameworkCoreを使用したNCache

Entity Framework CoreとNCacheを使用するアプリケーションの間にキャッシュのレイヤーを追加できます。これにより、クエリの応答時間が改善され、NCacheのキャッシュされたエンティティからデータを取得する限り、データベースへのラウンドトリップの必要性が減ります。 

キャッシングオプション

NCacheを使用すると、各リクエストから送信されるオプションのセットを変えることができます。つまり、効率を上げるために、使用している結果セットに基づいてキャッシュを異なる方法で使用できます。

実際のサンプルで見るように、NCacheへの各リクエストでキャッシュオプションを提供する必要があり、それらのオプションは次のとおりです。

  • AbsoluteExpirationTimeは、キャッシュされたアイテムが期限切れになる絶対時間を設定します。
    • データ型:日時
  • CreateDbDependencyは、結果セットからデータベースの依存関係を作成するかどうかを決定します。
    • データ型:ブール値
  • ExpirationTypeは、有効期限タイプを設定します。
    • 絶対の、
    • スライディング、
    • なし。
  • IsSyncEnabledは、期限切れのアイテムをデータベースと再同期する必要があるかどうかを設定します。
    • データ型:ブール値
  • 優先度、キャッシュに保存されているアイテムの相対的な優先度を設定します。
    • 普通、
    • 低い、
    • ノーマル以下、
    • 通常より上、
    • 高い、
    • 取り外し不可、
    • デフォルト
  • QueryIdentifier、結果セット識別子。
    • データ型:文字列。
  • ReadThruProviderは、キャッシュ同期用の読み取りスループロバイダーを設定します
    • データ型:文字列
  • SlidingExpirationTimeは、スライドの有効期限を設定します
    • データ型:TimeSpan
  • StoreAsは、アイテムの保存方法を設定します。
    • コレクション
    • SeperateEntities

延期された通話

NCacheには、Entity Framework Coreの遅延呼び出しを処理するための独自の拡張メソッドがあり、それらは3つの異なるグループに属しています。

  • 演算子を集約し、コレクションに対して操作を行います。FromCacheメソッドとFromCacheOnlyメソッドの両方で使用できます。
    • DeferredAverage。
      • Products.Select(o => o.UnitPrice).DeferredAverage()
    • DeferredCount
      • Customers.Select(c => c.Country).GroupBy(c => c).DeferredCount()
    • DeferredMin
      • Orders.Where(o => o.CustomerId == "VINET")。Select(o => o.RequiredDate).DeferredMin()
    • DeferredMax
      • Orders.Select(o => o.RequiredDate).DeferredMax()
    • DeferredSum
      • OrderDetails.Select(o => o.UnitPrice).DeferredSum()
  • 要素演算子、単一要素の操作を行います。FromCacheメソッドでのみ使用できます。
    • DeferredElementAtOrDefault
      • Customers.DeferredElementAtOrDefault(c => c.City == "London")
    • DeferredFirst
      • Customers.DeferredFirst(c => c.ContactTitle == "営業担当者")
    • DeferredFirstOrDefault
      • Customers.DeferredFirstOrDefault(c => c.ContactTitle == "営業担当者")
    • DeferredLast
      • Customers.DeferredLast(c => c.City == "London")
    • DeferredLastOrDefault
      • Customers.DeferredLastOrDefault(c => c.City == "London")
    • DeferredSingle
      • Customers.DeferredSingle(c => c.CustomerId == "ALFKI")
    • DeferredSingleOrDefault
      • Customers.DeferredSingleOrDefault(c => c.CustomerId == "ANATR")
  • その他。FromCacheメソッドでのみ使用できます。
    • DeferredAll
      • Products.DeferredAll(式)
    • DeferredLongCount
      • Products.DeferredLongCount()
    • DeferredContains
      • Products.DeferredContains(new Products {ProductId = 1})

キャッシング方法

キャッシュされたオブジェクトを操作するNCacheのメソッド:

  • 入れる

独自のオプションを使用して、単一のオブジェクトをキャッシュに挿入します。キャッシュキーを返します

var customerEntity = new Customers
   {
       CustomerId = "HANIH",
       ContactName = "Hanih Moos",
       ContactTitle = "Sales Representative ",
       CompanyName = "Blauer See Delikatessen"
   };

   //Add customer entity to database
   database.Customers.Add(customerEntity);
   database.SaveChanges();

   //Caching options for cache
   var options = new CachingOptions
   {
       QueryIdentifier = "CustomerEntity",
       Priority = Runtime.CacheItemPriority.Default,
   };

   //Add customer entity to cache
   Cache cache = database.GetCache();

   cache.Insert(customerEntity, out string cacheKey, options);
  • 削除(オブジェクトエンティティ)

キャッシュから1つのオブジェクトを削除します。

var cust = new Customers
  {
      CustomerId = "HANIH",
      ContactName = "Hanih Moos",
      ContactTitle = "Sales Representative",
      CompanyName = "Blauer See Delikatessen"
  };

  cache.Remove(cust);
  • 削除(文字列cacheKey)

キャッシュキーを渡してオブジェクトを削除します

cache.Remove("cacheKey");
  • RemoveByQueryIdentifier

クエリ識別子に一致するすべてのエンティティをキャッシュから削除します

Tag tag = new Tag(queryIdentifier);
cache.RemoveByQueryIdentifier(tag);

NCache拡張メソッドを使用したキャッシュ 

EntityFrameworkCore用のNCacheの拡張メソッド

  • GetCache

キャッシュインスタンスを取得します。

using (var context = new NorthwindContext())
{
Cache cache = context.GetCache();
}
  • FromCache

キャッシュされたデータがある場合は、データソースを経由せずに返されます。キャッシュされたデータがない場合、データはデータソースから返され、キャッシュされます。

var options = new CachingOptions
{
    StoreAs = StoreAs.SeperateEntities
};

var resultSet = (from cust in context.Customers
                 where cust.CustomerId == 10
                 select cust).FromCache(options);

結果セットからcacheKeyを返す

var options = new CachingOptions
{
    StoreAs = StoreAs.Collection
};

var resultSet = (from cust in context.Customers
                where cust.CustomerId == 10
                select cust).FromCache(out string cacheKey, options);
  • LoadIntoCache

すべてのリクエストは最初にデータソースに送られ、その結果セットをキャッシュして返します。

var options = new CachingOptions
    {
        StoreAs = StoreAs.SeperateEntities
    };

    var resultSet = (from custOrder in context.Orders
                     where custOrder.Customer.CustomerId == 10
                     select custOrder)).LoadIntoCache(options);

結果セットからキャッシュキーを返す

var options = new CachingOptions
{
    StoreAs = StoreAs.Collection
};

var resultSet = (from custOrder in context.Orders
                 where custOrder.Customer.CustomerId == 10
                 select custOrder)).LoadIntoCache(out string cacheKey, options);
  • FromCacheOnly

データソースには絶対に行きません。リクエストはキャッシュにのみ送信されます。一致する結果がキャッシュされていない場合は、空の結果セットとして返されます。

インクルードと結合はFromCacheOnly()ではサポートされていません。

var resultSet = (from cust in context.Customers
                 where cust.CustomerId == someCustomerId
                 select cust).FromCacheOnly();

NCacheの実装ステップバイステップ

0.前提条件

1.アプリケーション

  • .NET 6.0を対象とするC#コンソールアプリケーションを作成し、次のnugetsパッケージをインストールします。
    • EntityFrameworkCore.NCache
    • Microsoft.EntityFrameworkCore.SqlServer
    • Microsoft.EntityFrameworkCore.SqlServer.Design
    • Microsoft.EntityFrameworkCore.Tools
    • System.Data.SqlClient
    • System.Collections
  • Nugetパッケージをインストールすると、次のNCacheファイルがプロジェクトに挿入されます。
    • client.ncconf
    • config.ncconf
    • tls.ncconf

2.モデル

このサンプルでは、​​次のように非常に単純なモデル関係が作成されました。

  • 製品
[Serializable]
public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public double Price { get; set; }
    public List<Transaction> Transactions { get; set; }
    public Store Store { get; set; }
    public int? StoreId { get; set; }
}
[Serializable]
public class Store
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Location { get; set; }
    public ICollection<Product> AvailableProducts { get; set; }
    public ICollection<Consumer> RegularConsumers { get; set; }
}
  • 消費者
[Serializable]
public class Consumer
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Store FavouriteStore { get; set; }
    public int? FavouriteStoreId { get; set; }
    public List<Transaction> Transactions { get; set; }
}
  • 取引
[Serializable]
public class Transaction
{
     public int Id { get; set; }

     public Consumer Consumer { get; set; }
     public int ConsumerId { get; set; }

     public Product Product { get; set; }
     public int ProductId { get; set; }
}
  • DBContext

DBContextクラスには、NCache初期化設定とモデルの関係があります。

public class SampleDbContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        // configure cache with SQLServer DependencyType and CacheInitParams
        CacheConnectionOptions initParams = new CacheConnectionOptions();
        initParams.RetryInterval = new TimeSpan(0, 0, 5);
        initParams.ConnectionRetries = 2;
        initParams.ConnectionTimeout = new TimeSpan(0, 0, 5);
        initParams.AppName = "appName";
        initParams.CommandRetries = 2;
        initParams.CommandRetryInterval = new TimeSpan(0, 0, 5);
        initParams.Mode = IsolationLevel.Default;

        NCacheConfiguration.Configure("democache", DependencyType.SqlServer, initParams);

        optionsBuilder.UseSqlServer(@"Data Source=DESKTOP-AT3H2E;Initial Catalog=sampleDatabase;Integrated Security=True");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Store>()
            .HasMany(x => x.AvailableProducts)
            .WithOne(x => x.Store)
            .HasForeignKey(x => x.StoreId)
            .IsRequired(false)
            .OnDelete(DeleteBehavior.NoAction);

        modelBuilder.Entity<Store>()
            .HasMany(x => x.RegularConsumers)
            .WithOne(x => x.FavouriteStore)
            .HasForeignKey(x => x.FavouriteStoreId)
            .IsRequired(false)
            .OnDelete(DeleteBehavior.NoAction);

        modelBuilder.Entity<Transaction>()
            .HasOne(x => x.Consumer)
            .WithMany(x => x.Transactions)
            .HasForeignKey(x => x.ConsumerId)
            .IsRequired(false);

        modelBuilder.Entity<Transaction>()
            .HasOne(x => x.Product)
            .WithMany(x => x.Transactions)
            .HasForeignKey(x => x.ProductId)
            .IsRequired(false);
    }

    public DbSet<Store> Stores { get; set; }
    public DbSet<Consumer> Consumers { get; set; }
    public DbSet<Product> Products { get; set; }
    public DbSet<Transaction> Transactions { get; set; }
}

3.NCacheメソッド

これは、キャッシュとの間でオブジェクトを操作するために必要なNCacheメソッドを持つクラスです。

public class NCacheExtensions
{
    private SampleDbContext Database { get; set; }
    private CachingOptions CachingOptions { get; set; }
    private Cache Cache { get; set; }

    public NCacheExtensions(SampleDbContext database)
    {
        this.Database = database;
        this.CachingOptions = new CachingOptions
        {
            QueryIdentifier = "Sample QueryIdentifier",
            Priority = Alachisoft.NCache.Runtime.CacheItemPriority.Default,
            CreateDbDependency = false,
            StoreAs = StoreAs.Collection
        };

        Cache = database.GetCache();
    }

    public string AddSingleEntity<T>(T entity)
    {
        Cache.Insert(entity, out string cacheKey, this.CachingOptions);
        return cacheKey;
    }
    public void RemoveSingleEntity<T>(T entity)
    {
        Cache.Remove(entity);
    }
    public void RemoveSingleEntity(string cacheKey)
    {
        Cache.Remove(cacheKey);
    }
    public void RemoveByQueryIdentifier(string queryIdentifier)
    {
        var tag = new Tag(queryIdentifier);
        Cache.RemoveByQueryIdentifier(tag);
    }

    public IEnumerable<Consumer> GetAllConsumersFromCache(CachingOptions cachingOptions)
    {
        return Database.Consumers.Include(x => x.Transactions).ThenInclude(x => x.Product).FromCache(cachingOptions);
    }
    public async Task<IEnumerable<Consumer>> GetAllConsumersFromCacheAsync(CachingOptions cachingOptions)
    {
        return await Database.Consumers.Include(x => x.Transactions).ThenInclude(x => x.Product).FromCacheAsync(cachingOptions);
    }
    public IEnumerable<Consumer> LoadAllConsumersIntoCache(CachingOptions cachingOptions)
    {
        return Database.Consumers.Include(x => x.Transactions).ThenInclude(x => x.Product).LoadIntoCache(cachingOptions);
    }
    public async Task<IEnumerable<Consumer>> LoadAllConsumersIntoCacheAsync(CachingOptions cachingOptions)
    {
        return await Database.Consumers.Include(x => x.Transactions).ThenInclude(x => x.Product).LoadIntoCacheAsync(cachingOptions);
    }
    public IEnumerable<Consumer> GetAllConsumersFromCacheOnly(CachingOptions cachingOptions)
    {
        return Database.Consumers.FromCacheOnly();
    }
}

4.program.csクラス

ここに、コンソールアプリケーションの開始点があります。NCacheに接続し、上記で提供された拡張メソッドを使用する方法の例を示します。

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Hello World!");

        using (var context = new SampleDbContext())
        {
            var cachedContext = new NCacheExtensions(context);

            Console.WriteLine("start LoadAllConsumersIntoCache " + DateTime.Now.ToString("HH:mm:ss.f"));
            var loadInCache = cachedContext.LoadAllConsumersIntoCache(new CachingOptions { StoreAs = StoreAs.Collection, QueryIdentifier = "Sample QueryIdentifier" });
            Console.WriteLine("finish LoadAllConsumersIntoCache" + DateTime.Now.ToString("HH:mm:ss.f"));

            Console.WriteLine("start GetAllConsumersFromCache " + DateTime.Now.ToString("HH:mm:ss.f"));
            var getFromCache = cachedContext.GetAllConsumersFromCache(new CachingOptions { Priority = Alachisoft.NCache.Runtime.CacheItemPriority.Default });
            Console.WriteLine("finish GetAllConsumersFromCache " + DateTime.Now.ToString("HH:mm:ss.f"));

            Console.WriteLine("start load from DBContext " + DateTime.Now.ToString("HH:mm:ss.f"));
            var getFromDb = context.Consumers.Include(x => x.Transactions).ThenInclude(x => x.Product);
            Console.WriteLine("finishg load from DBContext " + DateTime.Now.ToString("HH:mm:ss.f"));

            var cachedEntity = cachedContext.AddSingleEntity<Consumer>(getFromDb.FirstOrDefault());
            Console.WriteLine("cache key: " + cachedEntity);

            cachedContext.RemoveSingleEntity(cachedEntity);
            cachedContext.RemoveByQueryIdentifier("Sample QueryIdentifier");

        }
    }
}

アプリケーションの動作:

おめでとう!これで、EntityFrameworkCoreデータをキャッシュするためのNCacheの使用に成功しました。

このストーリーは、もともとhttps://www.c-sharpcorner.com/article/caching-in-entity-framework-core-using-ncache/で公開されました

#entity-framework 

NCacheを使用したEntityFrameworkCoreでのキャッシュ
坂本  篤司

坂本 篤司

1652442480

VUE.JS、.NET 5、EntityFramework5 を使用したWeb開発

Webアプリケーションは、今日最も人気のあるアプリケーションです。新しいWebプロジェクトを開始するときは、Spring、Ruby、Django、PHP、ASP.NETなどのWebアプリケーションフレームワークと、React、Vue、AugularなどのJavaScriptベースのフレームワークを複数選択できます。これらすべてのフレームワークの中で、Vueはgithub(コレクション:フロントエンドJavaScriptフレームワーク・GitHub)によると最もスターの付いたWebフレームワークです。2014年に作成されたばかりですが、ますます人気が高まっています。

Webアプリケーションは、サーバー側のコンポーネントなしでは成功できません。ユーザー入力に応じて動的コンテンツを提供する必要があります。現在、.NET 5は、Microsoftの最新のサーバー側開発フレームワークであり、.NETFrameworkと.NETCoreを1つの統合フレームワークに統合しています。.NET 5で開発されたサービスは、Windows、Linux、macOSで共有できます。

Webアプリケーションで収集されたデータも、保存してアクセスする必要があります。現在、さまざまなストレージメカニズムがありますが、サーバー側の開発フレームワークとして.NET 5を使用する場合、データレイヤーテクノロジフレームワークの性質上、EntityFramework5とSQLServerが選択されます。

このシリーズでは、高校生が他に誰が応募したい大学に応募しているかを確認し、GPA、SATスコアなどの他の学生の統計を確認できる完全に機能するWebアプリケーションを開発します。これは、学生が特定の大学に出願すべきかどうか、もしそうなら、どのタイプ(ED、EA、またはRD)に出願するかを決定するのに役立ちます。

VUEを使用してフロントエンドUIを開発し、すべてのデータをSQLServerデータベースに保存します。Microsoft .NET 5を使用してサーバー側APIを開発し、EntityFramework5を使用してSQLServerデータベースに格納されているデータにアクセスします。

この記事シリーズの内容

  • Webアプリを構築し、Webアプリに必要なソフトウェアをインストールし、Webフロントエンドのスケルトンを作成します。
  • Vueルーターを追加し、ナビゲーションメニューを追加し、すべてのページを接続します。
  • Vuexを追加して、アプリケーションの状態を管理します。
  • MyStatsページにコントロールを追加し、MyStatsページに必要なすべてのコントロールを作成します。
  • MyCollegesページにコントロールを追加し、MyCollegesページに必要なすべてのコントロールを作成します。
  • サービスプロジェクトの作成、サービス開発に必要なソフトウェアのインストール、サービスプロジェクトの作成、サービスのモデルとコントローラーの追加
  • サービスを呼び出すと、Vueフロントエンドをサービスバックエンドに接続します。
  • データベースを準備し、SQL Serverをインストールして、テーブルを作成します。
  • データアクセス層を追加し、Entity Frameworkパッケージをインストールして、dbコンテキストリポジトリクラスを作成します。
  • サービスをデータアクセスオブジェクトに接続し、サービスをリポジトリに接続して、データベースからデータを取得します。
  • データベースへのデータの保存
  • アプリをパーソナライズし、ユーザープロファイルとログイン情報を追加します

前提条件

  • Microsoft .NET 5
  • Microsoft Visual Studio Community 2019
  • SQL Server 2019 Express
  • SQL Server Management Studio
  • ウインドウズ10

このシリーズの対象者

このシリーズは、Webフロントエンドを使用したエンタープライズアプリケーション開発を学びたい開発者を対象としています。JavaScript / Vueフレームワーク、.NET 5、およびEntity Framework 5の学習に興味がある場合は、このシリーズがぴったりです。Vueを使用してWebフロントエンドを開発する方法、Webをバックエンドの.NET 5サービスに接続する方法、および.NET5サービスからSQLServerデータベースを操作する方法を学習します。Web UI、サービスコンポーネント、およびエンティティフレームワークの開発のあらゆる側面を学習します。

このシリーズから学ぶこと

  • VUE.jsフレームワークを使用してWebフロントエンドを作成する
  • Vuexを使用してWebアプリケーションのアプリケーション状態を管理する
  • Webフロントエンドにサービスを提供する.NET5サービスを構築します
  • EntityFramework5を使用してデータにアクセスして操作する
  • フロントエンドからバックエンドまで完全に機能するWebアプリケーションを構築する

Webインターフェイスから始めます。ただし、最初に、このWebアプリケーションの目的と機能を理解していることを確認しましょう。

高校生にとって、3年生は忙しくてやりがいのある年です。学生は、優れたGPAを維持し、国内および/または国際大会に参加し、スポーツプログラムに参加し、クラブに参加し、パートタイムで働き、特定の組織でボランティアをし、そして最も重要なことに、大学に応募する必要があります。

問題は、学生が大学に出願しているとき、学生は他に誰が同じ大学に出願しているのかわからないということです。たぶん、はるかに優れた別の学生がすでに大学に出願しており、通常、その大学はこの高校から1人の学生しか受け入れないので、学生は本当にその大学を避ける必要があります。これは、アーリーディシジョンカレッジにとって特に重要です。これは、機会が1つしかない学生にとって最善の策だからです。多くの場合、学生は、プロセス全体が終了した後、「自分が応募していることを知っていれば、その大学には応募しなかっただろう」と言います。Navianceは、同じ高校の誰が特定の大学に出願したか、そして彼らがどれほど優秀であったかを学生が特定するのに役立ちますが、今年の学生の出願には役立ちません。

このシリーズでは、高校生がこの問題を解決するために使用できるWebアプリケーションを構築します。高校生は、このWebアプリケーションを使用して、大学に出願するときに自分の情報を入力したり、他の学生の情報を確認したりできます。

  1. 学生は、GPA、SAT / ACTスコア、競技会、クラブ、仕事、ボランティア時間などの情報を入力します。
  2. 学生はまた、彼/彼女が申請しようとしている大学に入学します。
  3. その後、学生は他に誰が同じ大学に出願しているか、そして彼らがどれほど優れているかを確認することができます。
  4. 学生は、Webアプリケーションからの情報に従って自分の大学リストを調整します。

次に、Vue、.NET 5、およびEntityFramework5を使用してこのWebアプリケーションを構築します。

必要なソフトウェアをインストールする

Webアプリケーションを構築するには、最初にいくつかのソフトウェアをインストールする必要があります。このシリーズで使用するソフトウェアはすべて無料なので、指定したWebアドレスからダウンロードできます。

以下は、この記事のためにインストールする必要のあるソフトウェアのリストです。

  1. https://nodejs.org/en/download/からNode.jsをインストールします。マシンの設定に応じて、Windowsインストーラー(.msi)32ビットまたは64ビットを選択します。この記事の執筆時点では、Nodeバージョン14.17.0を使用していましたが、現在のバージョンも使用できるはずです。
  2. https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd?hl=enからVue.jsDevToolsをインストールします。これは、Webアプリケーションのトラブルシューティングを行うときに非常に役立つChromeプラグインです。
  3. https://visualstudio.microsoft.com/downloads/からVisualStudio2019コミュニティをインストールします。コミュニティバージョンを選択し、Node.js開発ワークロードを確認してください。後で.NET5サービスを作成するためにこれが必要になるため、「ASP.NETおよびWeb開発」ワークロードも確認する必要があります。

Webプロジェクトを作成する

Webプロジェクトの作成から始めましょう。後の記事で.NET5.0サービスとEntityFrameworkを追加します。

次の手順に従って、Webプロジェクトを作成できます。

  1. VisualStudio2019を開始します
  2. 起動ダイアログの右側にある[新しいプロジェクトの作成]オプションを選択します。
  3. 検索ボックスにvueと入力します
  4. テンプレートとして「BasicVue.jsWebApplication」を選択します。TypeScriptではなく、JavaScriptバージョンのテンプレートが選択されていることを確認してください。Vue.jsテンプレートが表示されていない場合、Node.js開発ロードはVisualStudioにインストールされていません。前のセクションを確認して、この負荷をインストールできます。
  5. [次へ]ボタンをクリックします
  6. プロジェクト名としてWhoisApplyingWeb、場所としてC:\、ソリューション名としてWhoisApplyingを入力します。
  7. 「ソリューションとプロジェクトを同じディレクトリに配置する」のチェックを外したままにします。
  8. [作成]ボタンをクリックします。

これで、空のvue.jsWebプロジェクトが作成されました。それをテストするには、次の手順に従います。

  1. Visual Studioが必要なJavaScriptライブラリのソリューションへのダウンロードを完了するまで、数分待ちます。すべてのファイルがローカルマシンにダウンロードされるまでに最大5分かかる場合があります。
  2. ソリューションエクスプローラーで、WhoisApplyingWebプロジェクトを右クリックします。
  3. 「ここでコマンドプロンプトを開く…」を選択します。
  4. 「npmrunserve--- port 1337」(引用符は含めないでください)と入力し、Enterキーを押します。
  5. 次の画像のような実行中のコマンドウィンドウが表示されます。

これは、Webアプリケーションがポート1337で実行されていることを示しています。Webブラウザを開いて、ブラウザに次のアドレスを入力できます。

http://localhost:1337/

次に、Vue.jsで作成されたHelloworldWebアプリが表示されます。

アプリケーションに最初のページを追加する

次に、プロジェクトに3ページを追加して、学生がステータスと申請する大学を入力できるようにします。学生は、他に誰が同じ大学に出願しているのかを問い合わせることもできます。また、Webの説明を表示したり、他のページへのリンクを追加したりするためのホームページを作成します。

まず、プロジェクトにいくつかの変更を加えて、次回VisualStudio内から直接実行できるようにします。

  1. Webブラウザを閉じます。
  2. コマンドウィンドウを閉じます。
  3. Visual Studioに移動し、プロジェクトでファイルpackage.jsonを開きます

スクリプト/サーブノードに--port1337を追加して、サーブノードが次のようになるようにします。

"serve": "vue-cli-service serve --port 1337"

JavaScript

次にF5を押します。

これでコマンドウィンドウが開き、アプリケーションがコマンドウィンドウ内でコンパイルされます。以前と同じURLでWebブラウザも開いています。「このページに到達できません」と表示されるはずですが、ビルドが完了すると、ページが更新され、HelloWorldページが表示されます。

次に、学生が統計を入力するためのページを追加します。次の手順に従って、このWebページを作成できます。

  1. Visual Studio内で、プロジェクトにファイルを追加するため、デバッグを停止します。
  2. ソリューションエクスプローラー内で、srcフォルダーの下に新しいフォルダービューを作成します
  3. 新しく作成されたビューフォルダを右クリックして、「追加\新しいアイテム…」を選択します。
  4. 名前としてMyStats.vueを入力します

この新しいファイルに次のHTMLコードを入力します。

<template>
    <div>
        <div id="title">
            Please Enter Your Stats Below
        </div>
        <hr />
        <table id="myStatsTable">
            <tr>
                <td>Your High School:</td>
                <td></td>
            </tr>
            <tr>
                <td>Your SAT Score:</td>
                <td></td>
            </tr>
        </table>
    </div>
</template>

JavaScript

このページに入力したのは、Vueのテンプレートです。Vueの場合、すべてのコンポーネントは1つのルート要素を持つテンプレートです。最初のページでは、ルート要素はdivです。また、ページにいくつかの静的コントロールを追加しました。これは現在、学生統計の単なるプレースホルダーであることに注意してください。サイトが稼働したら、このページを後でカスタマイズします。

次に、テンプレート部分の後に、この新しいファイルに次のコードを追加します。

<script>
    export default {
        name: 'MyStats'
    };
</script>

JavaScript

ここで、このページのスクリプトを作成します。後で戻ってJavaScriptコードを追加します。今のところ、このページの名前をMyStatsに指定しました。

アプリケーションに2番目のページを追加

学生が統計を入力するためのページを追加しました。次に、学生が申請する大学に入力するための別のページを追加します。前のページと同じように、ほとんど空白のページから始めて、後でカスタマイズします。

次の手順に従って、この2番目のページを追加できます。

  1. src\viewsフォルダー内に新しいファイルMyColleges.vueを追加します
  2. この新しいファイルに次のHTMLコードを追加します。
<template>
    <div id="title">
        Please Enter Your Colleges Below
    </div>
</template>

JavaScript

これは、このページの単なるプレースホルダーになりました。後で、このページにコンテキストを追加して、学生が現在の大学のリストを表示したり、リストから大学を追加/削除したりできるようにします。

この新しいファイルに次のスクリプトファイルを追加します。

<script>
    export default {
        name: 'MyColleges'
    };
</script>

JavaScript

アプリケーションに3番目のページを追加

3番目のページは、学生が他に同じ大学に出願している人を照会するためのプレースホルダーになります。前のページと同じように、ほとんど空白のページから始めて、後でカスタマイズします。

次の手順に従って、この3番目のページを追加できます。

  1. src\viewsフォルダー内にWhoIsApplying.vueという新しいファイルを追加します
  2. この新しいファイルに次のHTMLコードを追加します。
<template>
    <div>
        Who else is also applying to the same colleges?
    </div>
</template>

JavaScript

そして、この新しいファイルに次のJavaScriptコードを追加します。

<script>
    export default {
        name: 'WhoIsApplying'
    };
</script>

JavaScript

アプリケーションのホームページをカスタマイズする

これで、アプリケーションに3つのページがありますが、それらを表示できません。表示するには、さらに作業を行う必要があります。ただし、最初に、このアプリケーションのニーズを満たすためにホームページを少し変更しましょう。

  1. ファイルHome.vueをコンポーネントからビューに移動します
  2. このファイルへの参照を更新するように求められたら、[はい]を選択します
  3. ファイルHome.vueを開く
  4. Home.vueファイル内のテンプレートのdiv要素を次のように変更します。
<template>
  <div class="home">
    <h1>Who else in my school is Applying to my dream colleges? </h1>
    <p>Are you thinking to apply to a college but don't know who else in your school is also applying to the same college? </p>
    <p>Find out right here! </p>
    <p>But first, please enter your stats and your colleges so others can benefit too! </p>
    <p>You can enter your college information anonymously. Be honest, don't try to fool others, as you don't want others to enter wrong information to mislead you as well. </p>
    <button @click="MyStats">Enter your stats</button><p />
    <button @click="MyColleges">Enter your colleges</button><p />
    <button @click="WhoIsApplying">Who is applying to the same colleges? </button><p />
  </div>
</template>

JavaScript

このホームページでは、まずこのサイトの目的を説明し、3つのボタンを追加しました。各ボタンは別のページに移動します。

小道具セクションを次のスクリプトコードに置き換えます。

<script>
  export default {
    name: 'Home',
    methods: {
      MyStats() {
        alert("my stats")
      },
      MyColleges() {
        alert("my colledges")
      },
      WhoIsApplying() {
        alert("who is applying")
      }
    }
  }
</script>

JavaScript

ご覧のとおり、ボタンがクリックされると、メッセージが表示されるようになりました。後で、それを実際のリンクに置き換えて、そのボタンの特定のページに移動します。

  1. app.vueファイルを開く
  2. 3行目のHomeコンポーネントのmsgパラメーターを削除します

F5キーを押してアプリケーションを実行すると、3つのボタンがある新しいホームページが表示されます。これらの3つのボタンのいずれかをクリックすると、ポップアップメッセージが表示されます。

しかし、どうすればあるページから別のページに移動できますか?それが次の記事で行うことです。

ソース:https ://www.c-sharpcorner.com/article/web-development-with-vue-js-net-5-and-entity-framework-5-chapter-1/

#dotnet #entity-framework #web 

VUE.JS、.NET 5、EntityFramework5 を使用したWeb開発

Desarrollo Web con VUE.JS, .NET 5 y Entity Framework 5

Las aplicaciones web son las aplicaciones más populares en la actualidad. Al iniciar un nuevo proyecto web, tiene múltiples opciones para el marco de la aplicación web, como Spring, Ruby, Django, PHP, ASP.NET y marcos basados ​​en JavaScript como React, Vue y Augular. Entre todos estos frameworks, Vue es el framework web más destacado según github ( Colección: Frameworks JavaScript front-end · GitHub ). Solo se creó en 2014, pero se ha vuelto cada vez más popular.

Una aplicación web no puede tener éxito sin un componente del lado del servidor. Tiene que proporcionar contenido dinámico de acuerdo con la entrada del usuario. Ahora, .NET 5 es el marco de desarrollo del lado del servidor más reciente de Microsoft, que combina .NET framework y .NET core en un solo marco unificado. Los servicios desarrollados con .NET 5 se pueden compartir entre Windows, Linux y macOS.

Los datos que se recopilan en una aplicación web también deben guardarse y accederse. Hoy en día existen muchos mecanismos de almacenamiento diferentes, pero con .NET 5 como marco de desarrollo del lado del servidor, Entity Framework 5 y SQL Server son las opciones naturales para los marcos de trabajo de tecnología de capa de datos.

En esta serie, desarrollaremos una aplicación web completamente funcional que permita a los estudiantes de secundaria verificar quién más está solicitando ingreso a las universidades a las que les gustaría postularse y conocer las estadísticas de otros estudiantes, como GPA, puntajes SAT. Esto ayudará a los estudiantes a tomar decisiones sobre si deben postularse a una universidad en particular y, de ser así, con qué tipos (ED, EA o RD) postularse.

Usaremos VUE para desarrollar la interfaz de usuario de front-end y guardar todos los datos en una base de datos de SQL Server. Usaremos Microsoft .NET 5 para desarrollar API del lado del servidor y usaremos Entity Framework 5 para acceder a los datos almacenados en la base de datos de SQL Server.

Lo que cubre esta serie de artículos

  • Construye la aplicación web, instala el software necesario para la aplicación web y crea el esqueleto de la interfaz web.
  • Al agregar Vue Router, se agregan menús de navegación y se conectan todas las páginas.
  • Agregar Vuex, administra el estado de la aplicación.
  • Agregar controles a la página MyStats, creando todos los controles necesarios en la página MyStats.
  • Agregar controles a la página MyColleges, creando todos los controles necesarios en la página MyColleges.
  • Crea el proyecto de servicio, instala el software necesario para el desarrollo del servicio, crea el proyecto de servicio, agrega modelos y controladores para el servicio
  • Al invocar Servicios, conecta el front-end de Vue con el back-end del servicio.
  • Preparación de base de datos, instala SQL Server y crea tablas.
  • Al agregar la capa de acceso a datos, se instala el paquete Entity Framework y se crean las clases de repositorio de contexto de base de datos.
  • Al conectar el servicio con los objetos de acceso a datos, conecta el servicio con el repositorio para recuperar datos de la base de datos.
  • Guardar datos en la base de datos
  • Personalización de la aplicación, agrega perfil de usuario e información de inicio de sesión

Requisito previo

  • Microsoft .NET 5
  • Comunidad de Microsoft Visual Studio 2019
  • Servidor SQL 2019 Express
  • Estudio de administración de SQL Server
  • ventanas 10

Para quién es esta serie

Esta serie es para desarrolladores que desean aprender a desarrollar aplicaciones empresariales con un front-end web. Si está interesado en aprender JavaScript/Vue framework, .NET 5 y Entity Framework 5, entonces esta serie está aquí para usted. Aprenderá cómo desarrollar el front-end web con Vue, cómo conectar la web con el servicio back-end .NET 5 y cómo interactuar con una base de datos de SQL Server desde el servicio .NET 5. Aprenderá todos los aspectos de la interfaz de usuario web, el componente de servicio y los desarrollos del marco de la entidad.

Lo que aprenderás de esta serie

  • Cree un front-end web con el marco VUE.js
  • Administre el estado de la aplicación de la aplicación web con Vuex
  • Construya un servicio .NET 5 para servir el front-end web
  • Acceda y manipule datos con Entity Framework 5
  • Cree una aplicación web completamente funcional desde el front-end hasta el back-end

Comenzaremos con la interfaz web. Pero primero asegurémonos de entender para qué sirve esta aplicación web y cómo funcionará.

Para un estudiante de secundaria, el penúltimo año es un año ocupado y desafiante. El estudiante debe mantener un buen GPA, participar en competencias nacionales y/o internacionales, involucrarse en programas deportivos, unirse a clubes, trabajar a tiempo parcial, ser voluntario en ciertas organizaciones y, lo que es más importante, postularse a universidades.

El problema es que, cuando un estudiante está solicitando ingreso a una universidad, el estudiante no sabe quién más también está solicitando ingreso a la misma universidad. Tal vez otro estudiante que es mucho mejor ya se postula para la universidad y, por lo general, esa universidad solo acepta a un estudiante de esta escuela secundaria, por lo que el estudiante realmente debería evitar esa universidad. Esto es especialmente crítico para la universidad Early Decision, ya que es la mejor opción para un estudiante con una sola oportunidad. A menudo, un estudiante dice después de que finaliza todo el proceso que "si hubiera sabido que él / ella estaba solicitando, no habría aplicado a esa universidad". Naviance puede ayudar a un estudiante a identificar quiénes de la misma escuela secundaria aplicaron para cierta universidad y qué tan buenos fueron, pero no puede ayudar con las solicitudes de estudiantes del año actual.

En esta serie, crearemos una aplicación web que los estudiantes de secundaria pueden usar para resolver este problema. Un estudiante de secundaria puede usar esta aplicación web para ingresar su propia información y verificar la información de otros estudiantes al postularse a una universidad.

  1. Un estudiante ingresa su información como GPA, puntaje SAT/ACT, competencias, clubes, trabajos, horas de voluntariado, etc.
  2. El estudiante también ingresa a las universidades a las que se postulará.
  3. Luego, el estudiante puede verificar quién más está solicitando ingreso a la misma universidad y qué tan buenos son.
  4. El estudiante ajusta su lista de universidades de acuerdo a la información de la aplicación web.

A continuación, construiremos esta aplicación web con Vue, .NET 5 y Entity Framework 5.

Instalar el software necesario

Para construir la aplicación web, primero debemos instalar algún software. Todo el software que utilizamos en esta serie es gratuito, por lo que puede descargarlo desde las direcciones web especificadas.

La siguiente es la lista del software que necesitamos instalar para este artículo:

  1. Instale Node.js desde https://nodejs.org/en/download/ . Elija Windows Installer (.msi) de 32 bits o de 64 bits, según la configuración de su máquina. Al momento de escribir este artículo, usábamos la versión 14.17.0 de Node, pero también debería poder usar la versión actual.
  2. Instale Vue.js DevTools desde https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd?hl=en . Este es un complemento de Chrome que lo ayudará enormemente cuando solucione problemas de la aplicación web.
  3. Instale la comunidad de Visual Studio 2019 desde https://visualstudio.microsoft.com/downloads/ . Asegúrese de elegir la versión de la comunidad y verifique la carga de trabajo de desarrollo de Node.js. También debe verificar la carga de trabajo "ASP.NET y desarrollo web", ya que la necesitaremos para crear el servicio .NET 5 más adelante.

Crear el proyecto web

Comencemos con la creación del proyecto web. Agregaremos el servicio .NET 5.0 y Entity Framework en un artículo posterior.

Puedes seguir estos pasos para crear el proyecto web:

  1. Inicie Visual Studio 2019
  2. Seleccione la opción "Crear un nuevo proyecto" en el lado derecho del cuadro de diálogo de inicio.
  3. Escriba vue en el cuadro de búsqueda
  4. Seleccione "Aplicación web básica de Vue.js" como plantilla. Asegúrese de que esté seleccionada la versión de JavaScript de la plantilla, no la de TypeScript. Si no se muestra la plantilla de Vue.js, la carga de desarrollo de Node.js no está instalada en Visual Studio. Puede consultar la sección anterior para instalar esta carga.
  5. Haga clic en el botón Siguiente
  6. Ingrese WhoisApplyingWeb como el nombre del proyecto, C:\ como la ubicación y WhoisApplying como el nombre de la solución.
  7. Deje "Colocar la solución y el proyecto en el mismo directorio" sin marcar.
  8. Haga clic en el botón Crear.

Ahora se ha creado un proyecto web vue.js vacío. Para probarlo, puedes seguir estos pasos:

  1. Espere unos minutos para permitir que Visual Studio termine de descargar las bibliotecas de JavaScript necesarias para la solución. Puede tomar hasta 5 minutos para que todos los archivos se descarguen a su máquina local.
  2. En el Explorador de soluciones, haga clic con el botón derecho en el proyecto WhoisApplyingWeb.
  3. Seleccione "Abrir símbolo del sistema aquí...".
  4. Escriba "npm run serve ---port 1337" (no debe incluir las comillas) y luego presione enter.
  5. Debería ver una ventana de comando en ejecución como en esta imagen:

Esto nos dice que la aplicación web se está ejecutando ahora con el puerto 1337. Puede abrir un navegador web e ingresar esta dirección en el navegador:

http://localhost:1337/

entonces debería ver la aplicación web Hello world, creada con Vue.js:

Agregar la primera página a la aplicación

A continuación, agregaremos tres páginas a nuestro proyecto para que un estudiante pueda ingresar el estado y las universidades a las que postularse. El estudiante también puede consultar quién más está solicitando ingreso a las mismas universidades. También crearemos una página de inicio para mostrar alguna descripción de la web y añadir enlaces a otras páginas.

Primero hagamos algunos cambios en el proyecto, para que la próxima vez podamos ejecutarlo directamente desde Visual Studio:

  1. Cierre el navegador web.
  2. Cierra la ventana de comandos.
  3. Vaya a Visual Studio, abra el archivo package.json en el proyecto

Agregue --port 1337 a scripts/nodo de servicio para que el nodo de servicio sea así ahora,

"serve": "vue-cli-service serve --port 1337"

JavaScript

Ahora presione F5.

Ahora se abre una ventana de comandos y la aplicación se compila dentro de la ventana de comandos. Un navegador web también está abierto, con la misma URL que antes. Debería mostrar "no se puede acceder a esta página", pero cuando finalice la compilación, la página se actualizará y mostrará la página Hello World.

Ahora agregaremos una página para que el estudiante ingrese las estadísticas. Puedes seguir estos pasos para crear esta página web:

  1. Dentro de Visual Studio, deje de depurar ya que vamos a agregar archivos al proyecto.
  2. Dentro del Explorador de soluciones, cree una nueva vista de carpeta en la carpeta src
  3. haga clic con el botón derecho en la carpeta de vistas recién creada y seleccione "Agregar\Nuevo elemento..."
  4. Introduzca MyStats.vue como nombre

Ingrese el siguiente código HTML para este nuevo archivo,

<template>
    <div>
        <div id="title">
            Please Enter Your Stats Below
        </div>
        <hr />
        <table id="myStatsTable">
            <tr>
                <td>Your High School:</td>
                <td></td>
            </tr>
            <tr>
                <td>Your SAT Score:</td>
                <td></td>
            </tr>
        </table>
    </div>
</template>

JavaScript

Lo que hemos ingresado a la página es una plantilla para Vue. Para Vue, cada componente es una plantilla, con un elemento raíz. Para nuestra primera página, el elemento raíz es un div. también agregamos algunos controles estáticos a la página. Tenga en cuenta que ahora es solo un marcador de posición para las estadísticas de los estudiantes. Personalizaremos esta página más adelante una vez que tengamos el sitio en funcionamiento.

Ahora agregue el siguiente código a este nuevo archivo, después de la parte de la plantilla,

<script>
    export default {
        name: 'MyStats'
    };
</script>

JavaScript

Aquí es donde escribiremos el script para esta página. Volveremos más tarde para agregar más código JavaScript. Por ahora, solo especificamos que el nombre de esta página sea MyStats.

Agregar una segunda página a la aplicación

Hemos agregado una página para que el estudiante ingrese las estadísticas, luego agregaremos otra página para que el estudiante ingrese las universidades a las que se postulará. Igual que en la página anterior, comenzaremos con una página casi en blanco y luego la personalizaremos.

Puede seguir estos pasos para agregar esta segunda página:

  1. Agregue un nuevo archivo MyColleges.vue dentro de la carpeta src\views
  2. Agregue el siguiente código HTML a este nuevo archivo:
<template>
    <div id="title">
        Please Enter Your Colleges Below
    </div>
</template>

JavaScript

Esto ahora es solo un marcador de posición para esta página. Más tarde, agregaremos más contexto a esta página para que un estudiante pueda ver la lista de universidades actual, así como agregar o eliminar una universidad de la lista.

Agregue el siguiente archivo de script a este nuevo archivo,

<script>
    export default {
        name: 'MyColleges'
    };
</script>

JavaScript

Agregar tercera página a la aplicación

La tercera página será un marcador de posición para que el estudiante consulte quién más también está solicitando ingreso a las mismas universidades. Igual que en la página anterior, comenzaremos con una página casi en blanco y luego la personalizaremos.

Puede seguir estos pasos para agregar esta tercera página:

  1. Agregue un nuevo archivo WhoIsApplying.vue dentro de la carpeta src\views
  2. Agregue el siguiente código HTML a este nuevo archivo:
<template>
    <div>
        Who else is also applying to the same colleges?
    </div>
</template>

JavaScript

Y agregue el siguiente código JavaScript a este nuevo archivo,

<script>
    export default {
        name: 'WhoIsApplying'
    };
</script>

JavaScript

Personaliza la Página de Inicio de la Aplicación

Ahora tenemos tres páginas en nuestra aplicación pero no podemos verlas, necesitamos trabajar un poco más para mostrarlas. Pero primero cambiemos un poco la página de inicio para satisfacer nuestras necesidades para esta aplicación.

  1. Mueva el archivo Home.vue de componentes a vistas
  2. Seleccione Sí cuando se le solicite actualizar las referencias a este archivo
  3. Abrir archivo Home.vue
  4. Cambie el elemento div de la plantilla dentro del archivo Home.vue para que sea así:
<template>
  <div class="home">
    <h1>Who else in my school is Applying to my dream colleges? </h1>
    <p>Are you thinking to apply to a college but don't know who else in your school is also applying to the same college? </p>
    <p>Find out right here! </p>
    <p>But first, please enter your stats and your colleges so others can benefit too! </p>
    <p>You can enter your college information anonymously. Be honest, don't try to fool others, as you don't want others to enter wrong information to mislead you as well. </p>
    <button @click="MyStats">Enter your stats</button><p />
    <button @click="MyColleges">Enter your colleges</button><p />
    <button @click="WhoIsApplying">Who is applying to the same colleges? </button><p />
  </div>
</template>

JavaScript

En esta página de inicio, primero explicamos para qué sirve este sitio y agregamos 3 botones. Cada botón navegará a otra página.

Reemplace la sección de accesorios con el siguiente código de secuencia de comandos,

<script>
  export default {
    name: 'Home',
    methods: {
      MyStats() {
        alert("my stats")
      },
      MyColleges() {
        alert("my colledges")
      },
      WhoIsApplying() {
        alert("who is applying")
      }
    }
  }
</script>

JavaScript

Como puede ver, cuando se hace clic en un botón, ahora solo mostramos un mensaje. Luego lo reemplazaremos por un enlace real para navegar a una página específica para ese botón.

  1. Abra el archivo app.vue
  2. Elimine el parámetro msg del componente Inicio en la línea 3

Ahora, si presiona F5 para ejecutar la aplicación, verá la nueva página de inicio con tres botones. Al hacer clic en uno de estos tres botones, aparecerá un mensaje emergente.

Pero, ¿cómo podemos navegar de una página a otra página? Eso es lo que haremos en el próximo artículo.

Fuente: https://www.c-sharpcorner.com/article/web-development-with-vue-js-net-5-and-entity-framework-5-chapter-1/

#dotnet #entity-framework #web 

Desarrollo Web con VUE.JS, .NET 5 y Entity Framework 5

ASP.NET Web API Usando MVC Y JQuery Para Cargar Y Descargar Archivos

Web API es la mejor opción para crear un servicio orientado a recursos mediante HTTP/Restful y funciona bien con aplicaciones basadas en MVC. Para más detalles, visita este enlace.

Descripción

En esta sesión, le mostraré cómo insertar registros usando AP.NET Web API usando HttpClient para publicar los datos en SQL Server. En esta sesión, puede ver las operaciones de obtención y publicación de la API web. De otra manera, puedo decir que insertaremos y recuperaremos registros usando un evento de clic de botón.

Antes de pasar por esta sesión, visite mis sesiones anteriores:

Pasos a seguir.

Paso 1

Agregue una carpeta en la aplicación Web API para guardar los archivos cargados. Vaya a Explorador de soluciones> Haga clic con el botón derecho en Nombre del proyecto (API web)> Agregar> Nueva carpeta> Cambiar nombre de carpeta (aquí cambié el nombre de "cargar archivos").

Paso 2

Agregue un nuevo controlador en nuestra aplicación Web API. Haga clic con el botón derecho en la carpeta del controlador (en la aplicación API web) > Agregar > Controlador > Ingrese el nombre del controlador (UploadController) > seleccione "Controlador API vacío" en las opciones de Scaffolding > Agregar.

Referencia del código

using System;  
using System.Collections.Generic;  
using System.IO;  
using System.Linq;  
using System.Net;  
using System.Net.Http;  
using System.Threading.Tasks;  
using System.Web;  
using System.Web.Http;  
  
namespace SatyaWebApi.Controllers  
{  
    public class UploadController : ApiController  
    {  
        public Task<HttpResponseMessage> Post()  
        {  
            List<string> savedFilePath = new List<string>();  
            if (!Request.Content.IsMimeMultipartContent())  
            {  
                throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);  
            }  
            string rootPath = HttpContext.Current.Server.MapPath("~/uploadFiles");  
            var provider = new MultipartFileStreamProvider(rootPath);  
            var task = Request.Content.ReadAsMultipartAsync(provider).  
                ContinueWith<HttpResponseMessage>(t =>  
                {  
                    if (t.IsCanceled || t.IsFaulted)  
                    {  
                        Request.CreateErrorResponse(HttpStatusCode.InternalServerError, t.Exception);  
                    }  
                    foreach (MultipartFileData item in provider.FileData)  
                    {  
                        try  
                        {  
                            string name = item.Headers.ContentDisposition.FileName.Replace("\"", "");  
                            string newFileName = Guid.NewGuid() + Path.GetExtension(name);  
                            File.Move(item.LocalFileName, Path.Combine(rootPath, newFileName));  
  
                            Uri baseuri = new Uri(Request.RequestUri.AbsoluteUri.Replace(Request.RequestUri.PathAndQuery, string.Empty));  
                            string fileRelativePath = "~/uploadFiles/" + newFileName;  
                            Uri fileFullPath = new Uri(baseuri, VirtualPathUtility.ToAbsolute(fileRelativePath));  
                            savedFilePath.Add(fileFullPath.ToString());  
                        }  
                        catch (Exception ex)  
                        {  
                            string message = ex.Message;  
                        }  
                    }  
  
                    return Request.CreateResponse(HttpStatusCode.Created, savedFilePath);  
                });  
            return task;  
        }  
    }  
} 

Código Descripción

Se agregó una nueva acción en el controlador (en la aplicación Web API) para cargar el archivo. He mencionado la ruta del archivo de carga como se menciona a continuación.

string rootPath = HttpContext.Current.Server.MapPath("~/uploadFiles"); 

Después de una carga exitosa, descargue el archivo usando el código como se menciona a continuación.

try  
                        {  
                            string name = item.Headers.ContentDisposition.FileName.Replace("\"", "");  
                            string newFileName = Guid.NewGuid() + Path.GetExtension(name);  
                            File.Move(item.LocalFileName, Path.Combine(rootPath, newFileName));  
  
                            Uri baseuri = new Uri(Request.RequestUri.AbsoluteUri.Replace(Request.RequestUri.PathAndQuery, string.Empty));  
                            string fileRelativePath = "~/uploadFiles/" + newFileName;  
                            Uri fileFullPath = new Uri(baseuri, VirtualPathUtility.ToAbsolute(fileRelativePath));  
                            savedFilePath.Add(fileFullPath.ToString());  
                        } 

Se utilizan dos clases importantes, como se menciona a continuación.

MultipartFileStreamProvider Class
Suited for writing each MIME body parts of the MIME multipart message to a file using a FileStream.


MultipartFileData Class
Represents a multipart file data.

Cargue varios archivos mediante MultipartFormDataStreamProvider en ASP.NET WebAPI. El concepto se basa en Multipart/form-data en los que podemos POST no solo el contenido de varios archivos, sino también los campos de formulario regulares que estarán disponibles como NameValueCollection en el lado del servidor.

En este tutorial, también vemos cómo anular el comportamiento predeterminado de MultipartFormDataStreamProvider que almacena el nombre en un formato BodyPart_{GUID} único a un nombre mucho más significativo. También invocaremos nuestra API web usando Fiddler para publicar datos de archivos. Además, desarrollamos una aplicación de consola de muestra que publicará los datos del archivo utilizando la clase HttpClient.

 

Paso 3

Agregue una acción al HomeController (en la aplicación MVC Client) para obtener la vista del archivo cargado.

Referencia del código

public ActionResult Part5()  
        {  
            return View();  
        } 

Etapa 4

Agregar vista para la acción y el diseño. Haga clic con el botón derecho en el método de acción (aquí, haga clic con el botón derecho en la acción del formulario) > Agregar vista... > Ingresar nombre > Agregar.

Referencia del código

@{  
    ViewBag.Title = "Part5";  
}  
  
<style>  
    table {  
        font-family: arial, sans-serif;  
        border-collapse: collapse;  
        width: 100%;  
    }  
  
    td, th {  
        border: 1px solid #dddddd;  
        text-align: left;  
        padding: 8px;  
    }  
  
    tr:nth-child(even) {  
        background-color: #dddddd;  
    }  
  
    .button {  
        background-color: #4CAF50;  
        border: none;  
        color: white;  
        padding: 15px 32px;  
        text-align: center;  
        text-decoration: none;  
        display: inline-block;  
        font-size: 16px;  
        margin: 4px 2px;  
        cursor: pointer;  
    }  
  
    .button4 {  
        border-radius: 9px;  
    }  
</style>  
  
<fieldset>  
  
    <legend style="font-family:Arial Black;color:blue">Upload And Download Files Here</legend>  
  
    <div>  
        <div class="form-group">  
            <div id="updatePanelFile" class="alert" role="alert" style="display:none;">  
  
            </div>  
        </div>  
        <div class="col-md-12" style="text-align:center;margin-bottom:10px;">  
            <input type="file" id="file1" class="btn btn-primary" />  
        </div>  
        <input id="btnPostFile" class="button button4" type="button" value="Upload" />  
    </div>  
  
    @section Scripts{  
        <script>  
            $(document).ready(function () {  
                $('#btnPostFile').click(function () {  
                    if ($('#file1').val() == '') {  
                        alert('Please select file');  
                        return;  
                    }  
  
                    var formData = new FormData();  
                    var file = $('#file1')[0];  
                    formData.append('file', file.files[0]);  
                    $.ajax({  
                        url: 'http://localhost:47250/api/Upload',  
                        type: 'POST',  
                        data: formData,  
                        contentType: false,  
                        processData: false,  
                        success: function (d) {  
                            $('#updatePanelFile').addClass('alert-success').html('<strong>Upload Done!</strong><a href="' + d + '">Download File</a>').show();  
                            $('#file1').val(null);  
                        },  
                        error: function () {  
                            $('#updatePanelFile').addClass('alert-error').html('<strong>Failed!</strong> Please try again.').show();  
                        }  
                    });  
                });  
            });  
        </script>  
    }  
    </fieldset> 

Código Descripción

Agregue el siguiente jQuery usando la URL de la API web para cargar el archivo a la API web.

$.ajax({  
                        url: 'http://localhost:47250/api/Upload',  
                        type: 'POST',  
                        data: formData,  
                        contentType: false,  
                        processData: false,  
                        success: function (d) {  
                            $('#updatePanelFile').addClass('alert-success').html('<strong>Upload Done!</strong><a href="' + d + '">Download File</a>').show();  
                            $('#file1').val(null);  
                        } 

Una vez que el archivo se cargue correctamente, el enlace del archivo estará disponible para descargarlo mediante el panel.

success: function (d) {  
                            $('#updatePanelFile').addClass('alert-success').html('<strong>Upload Done!</strong><a href="' + d + '">Download File</a>').show();  
                            $('#file1').val(null);  
                        } 

Si nos enfrentamos a algún problema en la URL de la API web o en el servidor, recibiremos un mensaje de advertencia como se menciona a continuación.

error: function () {  
                            $('#updatePanelFile').addClass('alert-error').html('<strong>Failed!</strong> Please try again.').show();  
                        } 

PRODUCCIÓN

Sube el archivo aquí.

 

A continuación, el panel muestra la opción de descargar el archivo después de cargarlo correctamente en la API web.

 

Esta es la ruta de la API web donde los archivos se cargan con un nombre diferente.

 

Verifique todos los archivos cargados en la ruta URL de la API web.

 

Enlace al código fuente 

Resumen

  • Cargue archivos utilizando la API web y descargue archivos desde allí.
  • Implementación de la clase MultipartFileStreamProvider.
  • Implementación de la clase MultipartFileData.

Fuente: https://www.c-sharpcorner.com/article/asp-net-web-api-using-mvc-and-jquery-to-upload-files-part-seven2/ 

#aspdotnet #mvc #entity-framework 

ASP.NET Web API Usando MVC Y JQuery Para Cargar Y Descargar Archivos
藤本  結衣

藤本 結衣

1648898160

MVCとjQueryを使用してファイルをアップロードおよびダウンロードするASP.NETWebAPI

Web APIは、HTTP / Restfulを使用してリソース指向のサービスを作成するのに最適であり、MVCベースのアプリケーションでうまく機能します。詳細については、このリンクにアクセスしてください。

説明

このセッションでは、HttpClientを使用してAP.NET Web APIを使用してレコードを挿入し、SQLServerにデータを投稿する方法を説明します。このセッションでは、WebAPIによるgetおよびpost操作を確認できます。別の言い方をすれば、ボタンクリックイベントを使用してレコードを挿入および取得すると言えます。

このセッションを完了する前に、以前のセッションにアクセスしてください。

パート1- MVCとエンティティフレームワークを使用したASP.NETWebAPI

パート2-データを取得するためにMVC、エンティティフレームワーク、jQueryを使用するASP.NET Web API 

パート3- ASP.NETWebAPIでクラスライブラリを使用して、エンティティデータモデル(.edmx)のモデルクラスを複数のプロジェクトに再利用する

パート4- 

データを取得するためにMVC、Entity Framework、およびHttpClientを使用するASP.NET Web API

パート5-検証付きの取得と投稿にMVC、Entity Framework、jQueryを使用したASP.NET Web API  

パート6- 検証を使用して取得および投稿するためにMVC、Entity Framework、およびHttpClientを使用するASP.NET Web API

従うべきステップ。

ステップ1

アップロードされたファイルを保存するためのフォルダーをWebAPIアプリケーションに追加します。ソリューションエクスプローラーに移動し、プロジェクト名(Web API)を右クリック>追加>新しいフォルダー>フォルダーの名前を変更します(ここでは「uploadFiles」に名前を変更しました)。

ステップ2

WebAPIアプリケーションに新しいコントローラーを追加します。(Web APIアプリケーション内の)コントローラーフォルダーを右クリック>[追加]>[コントローラー]>コントローラー名を入力(UploadController)>[足場オプション]から[空のAPIコントローラー]を選択>[追加]。

コード参照

using System;  
using System.Collections.Generic;  
using System.IO;  
using System.Linq;  
using System.Net;  
using System.Net.Http;  
using System.Threading.Tasks;  
using System.Web;  
using System.Web.Http;  
  
namespace SatyaWebApi.Controllers  
{  
    public class UploadController : ApiController  
    {  
        public Task<HttpResponseMessage> Post()  
        {  
            List<string> savedFilePath = new List<string>();  
            if (!Request.Content.IsMimeMultipartContent())  
            {  
                throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);  
            }  
            string rootPath = HttpContext.Current.Server.MapPath("~/uploadFiles");  
            var provider = new MultipartFileStreamProvider(rootPath);  
            var task = Request.Content.ReadAsMultipartAsync(provider).  
                ContinueWith<HttpResponseMessage>(t =>  
                {  
                    if (t.IsCanceled || t.IsFaulted)  
                    {  
                        Request.CreateErrorResponse(HttpStatusCode.InternalServerError, t.Exception);  
                    }  
                    foreach (MultipartFileData item in provider.FileData)  
                    {  
                        try  
                        {  
                            string name = item.Headers.ContentDisposition.FileName.Replace("\"", "");  
                            string newFileName = Guid.NewGuid() + Path.GetExtension(name);  
                            File.Move(item.LocalFileName, Path.Combine(rootPath, newFileName));  
  
                            Uri baseuri = new Uri(Request.RequestUri.AbsoluteUri.Replace(Request.RequestUri.PathAndQuery, string.Empty));  
                            string fileRelativePath = "~/uploadFiles/" + newFileName;  
                            Uri fileFullPath = new Uri(baseuri, VirtualPathUtility.ToAbsolute(fileRelativePath));  
                            savedFilePath.Add(fileFullPath.ToString());  
                        }  
                        catch (Exception ex)  
                        {  
                            string message = ex.Message;  
                        }  
                    }  
  
                    return Request.CreateResponse(HttpStatusCode.Created, savedFilePath);  
                });  
            return task;  
        }  
    }  
} 

コードの説明

ファイルをアップロードするための新しいアクションを(Web APIアプリケーションの)コントローラーに追加しました。アップロードファイルのパスについては、以下で説明しました。

string rootPath = HttpContext.Current.Server.MapPath("~/uploadFiles"); 

アップロードが成功したら、以下のコードを使用してファイルをダウンロードします。

try  
                        {  
                            string name = item.Headers.ContentDisposition.FileName.Replace("\"", "");  
                            string newFileName = Guid.NewGuid() + Path.GetExtension(name);  
                            File.Move(item.LocalFileName, Path.Combine(rootPath, newFileName));  
  
                            Uri baseuri = new Uri(Request.RequestUri.AbsoluteUri.Replace(Request.RequestUri.PathAndQuery, string.Empty));  
                            string fileRelativePath = "~/uploadFiles/" + newFileName;  
                            Uri fileFullPath = new Uri(baseuri, VirtualPathUtility.ToAbsolute(fileRelativePath));  
                            savedFilePath.Add(fileFullPath.ToString());  
                        } 

以下に説明するように、2つの重要なクラスが使用されます。

MultipartFileStreamProvider Class
Suited for writing each MIME body parts of the MIME multipart message to a file using a FileStream.


MultipartFileData Class
Represents a multipart file data.

ASP.NETWebAPIのMultipartFormDataStreamProviderを使用して複数のファイルをアップロードします。この概念は、複数のファイルコンテンツだけでなく、サーバー側でNameValueCollectionとして使用できる通常のフォームフィールドもPOSTできるMultipart/form-dataに基づいています。

このチュートリアルでは、名前を一意のBodyPart_{GUID}形式でより意味のある名前に格納するMultipartFormDataStreamProviderのデフォルトの動作をオーバーライドする方法も示します。また、Fiddlerを使用してWeb APIを呼び出し、ファイルデータをPOSTします。同時に、HttpClientクラスを使用してファイルデータをPOSTするサンプルコンソールアプリケーションを開発します。

 

ステップ3

アップロードされたファイルのビューを取得するためのアクションを(MVCクライアントアプリケーションの)HomeControllerに追加します。

コード参照

public ActionResult Part5()  
        {  
            return View();  
        } 

ステップ4

アクションとデザインのビューを追加します。アクションメソッドを右クリックします(ここでは、フォームアクションを右クリックします)>[ビューの追加...]>[名前の入力]>[追加]。

コード参照

@{  
    ViewBag.Title = "Part5";  
}  
  
<style>  
    table {  
        font-family: arial, sans-serif;  
        border-collapse: collapse;  
        width: 100%;  
    }  
  
    td, th {  
        border: 1px solid #dddddd;  
        text-align: left;  
        padding: 8px;  
    }  
  
    tr:nth-child(even) {  
        background-color: #dddddd;  
    }  
  
    .button {  
        background-color: #4CAF50;  
        border: none;  
        color: white;  
        padding: 15px 32px;  
        text-align: center;  
        text-decoration: none;  
        display: inline-block;  
        font-size: 16px;  
        margin: 4px 2px;  
        cursor: pointer;  
    }  
  
    .button4 {  
        border-radius: 9px;  
    }  
</style>  
  
<fieldset>  
  
    <legend style="font-family:Arial Black;color:blue">Upload And Download Files Here</legend>  
  
    <div>  
        <div class="form-group">  
            <div id="updatePanelFile" class="alert" role="alert" style="display:none;">  
  
            </div>  
        </div>  
        <div class="col-md-12" style="text-align:center;margin-bottom:10px;">  
            <input type="file" id="file1" class="btn btn-primary" />  
        </div>  
        <input id="btnPostFile" class="button button4" type="button" value="Upload" />  
    </div>  
  
    @section Scripts{  
        <script>  
            $(document).ready(function () {  
                $('#btnPostFile').click(function () {  
                    if ($('#file1').val() == '') {  
                        alert('Please select file');  
                        return;  
                    }  
  
                    var formData = new FormData();  
                    var file = $('#file1')[0];  
                    formData.append('file', file.files[0]);  
                    $.ajax({  
                        url: 'http://localhost:47250/api/Upload',  
                        type: 'POST',  
                        data: formData,  
                        contentType: false,  
                        processData: false,  
                        success: function (d) {  
                            $('#updatePanelFile').addClass('alert-success').html('<strong>Upload Done!</strong><a href="' + d + '">Download File</a>').show();  
                            $('#file1').val(null);  
                        },  
                        error: function () {  
                            $('#updatePanelFile').addClass('alert-error').html('<strong>Failed!</strong> Please try again.').show();  
                        }  
                    });  
                });  
            });  
        </script>  
    }  
    </fieldset> 

コードの説明

ファイルをWebAPIにアップロードするために、WebAPIURLを使用して次のjQueryを追加します。

$.ajax({  
                        url: 'http://localhost:47250/api/Upload',  
                        type: 'POST',  
                        data: formData,  
                        contentType: false,  
                        processData: false,  
                        success: function (d) {  
                            $('#updatePanelFile').addClass('alert-success').html('<strong>Upload Done!</strong><a href="' + d + '">Download File</a>').show();  
                            $('#file1').val(null);  
                        } 

ファイルが正常にアップロードされると、パネルを使用してファイルリンクをダウンロードできるようになります。

success: function (d) {  
                            $('#updatePanelFile').addClass('alert-success').html('<strong>Upload Done!</strong><a href="' + d + '">Download File</a>').show();  
                            $('#file1').val(null);  
                        } 

Web API URLまたはサーバーの問題で問題が発生した場合は、以下のような警告メッセージが表示されます。

error: function () {  
                            $('#updatePanelFile').addClass('alert-error').html('<strong>Failed!</strong> Please try again.').show();  
                        } 

出力

ここにファイルをアップロードします。

 

以下のパネルには、WebAPIで正常にアップロードした後のファイルのダウンロードオプションが表示されています。

 

これは、ファイルが別の名前でアップロードされるWebAPIのパスです。

 

WebAPIURLパスにアップロードされたすべてのファイルを確認します。

 

ソースコードへのリンク 

概要

  • Web APIを使用してファイルをアップロードし、そこからファイルをダウンロードします。
  • MultipartFileStreamProviderクラスの実装。
  • MultipartFileDataクラスの実装。

ソース:https ://www.c-sharpcorner.com/article/asp-net-web-api-using-mvc-and-jquery-to-upload-files-part-seven2/

#aspdotnet #mvc #entity-framework 

MVCとjQueryを使用してファイルをアップロードおよびダウンロードするASP.NETWebAPI

Inserte Registros Usando AA Web API Usando HttpClient en SQL Server

Introducción

WEB API es la mejor opción para crear un servicio orientado a recursos mediante HTTP/Restful y funciona bien con aplicaciones basadas en MVC. Para más detalles visita mi enlace.

Descripción

En esta sesión, le mostraré cómo insertar registros usando AA Web API usando HttpClient para publicar datos en SQL Server. En esta sesión, puede ver las operaciones de obtención y publicación de la API web. De otra manera, puedo decir que insertaremos y recuperaremos registros usando un evento de clic de botón.

Antes de pasar por esta sesión, visite mi sesión anterior.

Pasos a seguir,

Paso 1

Agregue una nueva acción a HomeController (en la aplicación de cliente MVC) para obtener una vista de Obtener datos mediante el cliente HTTP.

Referencia del código

public ActionResult Part4()   
        {  
            List<Employee> list = new List<Employee>();  
            HttpClient client = new HttpClient();  
            var result = client.GetAsync("http://localhost:47250/api/satya").Result;  
            if (result.IsSuccessStatusCode)  
            {  
                list = result.Content.ReadAsAsync<List<Employee>>().Result;  
                ViewBag.userdetails = list;  
            }  
            return View();  
        } 

Código Descripción


 

Durante la carga inicial de la página, se mostrarán los datos de la tabla, lo que significa que los datos se vincularán en la tabla con controles de entrada utilizando HttpClient. Este método de acción del controlador con [HttpGet].

Paso 2

Usando la misma acción para HomeController (en la aplicación MVC Client) para publicar datos usando HTTP Client.

Referencia del código

[HttpPost]  
    public ActionResult Part4(Employee emp)   
    {  
        if (ModelState.IsValid)  
        {  
            HttpClient client = new HttpClient();  
            var result = client.PostAsJsonAsync("http://localhost:47250/api/satya", emp).Result;  
            if (result.IsSuccessStatusCode)  
            {  
                emp = result.Content.ReadAsAsync<Employee>().Result;  
                ViewBag.Result = "Data Is Successfully Saved!";  
                List<Employee> list = new List<Employee>();  
                HttpClient client1 = new HttpClient();  
                var result1 = client1.GetAsync("http://localhost:47250/api/satya").Result;  
                if (result1.IsSuccessStatusCode)  
                {  
                    list = result1.Content.ReadAsAsync<List<Employee>>().Result;  
                    ViewBag.userdetails = list;  
                }  
                ModelState.Clear();  
                return View(new Employee());  
            }  
            else  
            {  
                ViewBag.Result = "Error! Please try with valid data.";  
            }  
        }  
        return View(emp);  
    } 

Código Descripción

En esta parte, después del método de publicación de formulario o del evento de clic de botón, se mostrarán datos de inserción y tablas. En la sección de publicación lateral, agregué algo para la recuperación de datos; de lo contrario, obtendrá un error sobre la referencia del objeto que no se establece en una instancia de un objeto. Describiré este problema en la sección Ver en Nota.

  1. Lista<Empleado> lista =  new  Lista<Empleado>();
                    HttpClient client1 = new HttpClient();  
                    var result1 = client1.GetAsync("http://localhost:47250/api/satya").Result;  
                    if (result1.IsSuccessStatusCode)  
                    {  
                        list = result1.Content.ReadAsAsync<List<Employee>>().Result;  
                        ViewBag.userdetails = list;  
                    } 

Objeto de diccionario de estado del modelo que contiene el estado del modelo y de la validación del enlace del modelo, elimina todos los elementos del diccionario de estado del modelo.

ModelState.Clear(); 

Paso 3

Haga clic con el botón derecho en Método de acción (aquí, haga clic con el botón derecho en el formulario Part4()) > Agregar vista... > Marque "Crear vista fuertemente tipada" > Seleccione Clase de modelo >> Agregar. Aquí Model Class es "Empleado (Entidades)".

 

Referencia del código

@model Entities.Employee  
  
@{  
    ViewBag.Title = "Satyaprakash - Post data to Web API using HTTPClient (in MVC client application) With Validation";  
}  
  
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">  
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>  
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>  
  
  
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/4.4.0/bootbox.min.js">  
  
</script>  
  
<style>  
    span.field-validation-error {  
        color: red;  
    }  
  
    table {  
        font-family: arial, sans-serif;  
        border-collapse: collapse;  
        width: 100%;  
    }  
  
    td, th {  
        border: 1px solid #dddddd;  
        text-align: left;  
        padding: 8px;  
    }  
  
    tr:nth-child(even) {  
        background-color: #dddddd;  
    }  
  
    .button {  
        background-color: #4CAF50;  
        border: none;  
        color: white;  
        padding: 15px 32px;  
        text-align: center;  
        text-decoration: none;  
        display: inline-block;  
        font-size: 16px;  
        margin: 4px 2px;  
        cursor: pointer;  
    }  
  
    .button4 {  
        border-radius: 9px;  
    }  
</style>  
  
  
<div style="padding:10px ; align-content:center">  
    <fieldset>  
        <legend style="font-family:Arial Black;color:blue">Post data to Web API using HTTPClient (in MVC client application) With Validation</legend>  
    </fieldset>  
</div>  
  
  
<div style="max-width:600px;">  
    @using (Html.BeginForm("Part4", "Home", FormMethod.Post, new { role = "form" }))  
    {  
        @Html.ValidationSummary(true)  
  
        <div class="form-group">  
            @Html.LabelFor(a => a.FirstName)  
            @Html.TextBoxFor(a => a.FirstName, new { @class = "form-control" })  
            @Html.ValidationMessageFor(a => a.FirstName)  
        </div>  
        <div class="form-group">  
            @Html.LabelFor(a => a.LastName)  
            @Html.TextBoxFor(a => a.LastName, new { @class = "form-control" })  
            @Html.ValidationMessageFor(a => a.LastName)  
        </div>  
        <div class="form-group">  
            @Html.LabelFor(a => a.EmailID)  
            @Html.TextBoxFor(a => a.EmailID, new { @class = "form-control" })  
            @Html.ValidationMessageFor(a => a.EmailID)  
        </div>  
        <div class="form-group">  
            @Html.LabelFor(a => a.City)  
            @Html.TextBoxFor(a => a.City, new { @class = "form-control" })  
            @Html.ValidationMessageFor(a => a.City)  
        </div>  
        <div class="form-group">  
            @Html.LabelFor(a => a.Country)  
            @Html.TextBoxFor(a => a.Country, new { @class = "form-control" })  
            @Html.ValidationMessageFor(a => a.Country)  
        </div>  
        <input id="btn" type="submit" value="Create" class="button button4" />  
  
        <div style="width:90%; padding:10px; margin:0 auto;">  
            @if (ViewBag.Result != null)  
            {  
                @*<div style="color:red">@ViewBag.Result</div>*@  
  
                <script>  
                    $(document).ready(function () {  
                        $('#btn').click(function () {  
                            $('#tableshow').hide();  
                        });  
  
                        bootbox.alert('@ViewBag.Result');  
                        $('#tableshow').show();  
                    });  
                </script>  
            }  
        </div>  
    }  
</div>  
  
@*System.NullReferenceException , Object reference not set to an instance of an object. This error due to without added for data retrieve comment line code in Part4() in homecontroller in webapplication*@  
<div id="tableshow" style="width:90%; padding:10px; margin:0 auto;">  
    <table class="table table-responsive table-striped table-bordered">  
        <thead>  
            <tr>  
                <th style="background-color: Yellow;color: blue">Full Name</th>  
                <th style="background-color: Yellow;color: blue">Email</th>  
                <th style="background-color: Yellow;color: blue">City</th>  
                <th style="background-color: Yellow;color: blue">Country</th>  
            </tr>  
        </thead>  
        <tbody>  
            @foreach (var i in ViewBag.userdetails)   
            {  
                <tr>  
                    <td>@i.FirstName @i.LastName</td>  
                    <td>@i.EmailID</td>  
                    <td>@i.City</td>  
                    <td>@i.Country</td>  
                </tr>  
            }  
        </tbody>  
    </table>  
</div>  
@*System.NullReferenceException , Object reference not set to an instance of an object.*@  
  
@section Scripts{  
    @Scripts.Render("~/bundles/jqueryval")  
} 

Código Descripción

En esta sección de código dentro del método de publicación de formulario, se agregó una secuencia de comandos para que durante el clic del botón se muestren los datos de la tabla de eventos.

<div style="width:90%; padding:10px; margin:0 auto;">  
            @if (ViewBag.Result != null)  
            {  
                @*<div style="color:red">@ViewBag.Result</div>*@  
  
                <script>  
                    $(document).ready(function () {  
                        $('#btn').click(function () {  
                            $('#tableshow').hide();  
                        });  
  
                        bootbox.alert('@ViewBag.Result');  
                        $('#tableshow').show();  
                    });  
                </script>  
            }  
        </div> 

Aquí usé la biblioteca de bootbox para mostrar la notificación de alerta. ViewBag.Result contiene un mensaje en el método de acción del controlador.

bootbox.alert('@ViewBag.Result'); 

Nota 

Durante esta sesión, tuve un problema con System.NullReferenceException, la referencia del objeto no está configurada como una instancia de un objeto.

Por lo tanto, creé una identificación div y la puse dentro de la sección de script como se describe en el método de publicación del método de acción del controlador Part4(). Este error se debió a la falta de datos agregados para el código de línea de comentario de recuperación de datos en Part4() en homecontroller en la aplicación cliente MVC.

<div id="tableshow" style="width:90%; padding:10px; margin:0 auto;">  
    <table class="table table-responsive table-striped table-bordered">  
        <thead>  
            <tr>  
                <th style="background-color: Yellow;color: blue">Full Name</th>  
                <th style="background-color: Yellow;color: blue">Email</th>  
                <th style="background-color: Yellow;color: blue">City</th>  
                <th style="background-color: Yellow;color: blue">Country</th>  
            </tr>  
        </thead>  
        <tbody>  
            @foreach (var i in ViewBag.userdetails)   
            {  
                <tr>  
                    <td>@i.FirstName @i.LastName</td>  
                    <td>@i.EmailID</td>  
                    <td>@i.City</td>  
                    <td>@i.Country</td>  
                </tr>  
            }  
        </tbody>  
    </table>  
</div> 

PRODUCCIÓN

Durante el evento de carga de la página.

 

Soporte de vista móvil.

 

Imagen gif para una mejor comprensión de la salida.

 

Verifique el servidor sql para insertar registros como se muestra en la imagen de arriba.

 

Enlace al código fuente

RESUMEN

  • Obtenga y publique datos con validación de control de formulario utilizando HTTP Client.
     
  • Biblioteca javascript de Bootbox para mensajes de alerta.
  • Soporte de respuesta móvil.

Partes anteriores -

Parte 1: API web ASP.NET usando MVC y Entity Framework

Parte 2: ASP.NET Web API usando MVC, Entity Framework y jQuery para recuperar datos 

Parte 3: reutilice las clases de modelo del modelo de datos de entidad (.edmx) para múltiples proyectos usando la biblioteca de clases en ASP.NET Web API

Parte 4 - 

ASP.NET Web API usando MVC, Entity Framework y HttpClient para recuperar datos

Parte 5: ASP.NET Web API usando MVC, Entity Framework y jQuery para obtener y publicar con validación  

Fuente: https://www.c-sharpcorner.com/article/asp-net-web-api-using-mvc-entity-framework-and-httpclient-for-get-and-post-with/

#aspdotnet #mvc #entity-framework 

Inserte Registros Usando AA Web API Usando HttpClient en SQL Server
藤本  結衣

藤本 結衣

1648887900

HttpClientを使用してAAWebAPIを使用してレコードを挿入し、SQLでデータを投稿します

WEB APIは、HTTP / Restfulを使用してリソース指向のサービスを作成するのに最適であり、MVCベースのアプリケーションでうまく機能します。詳細については、私のリンクをご覧ください。

説明

このセッションでは、HttpClientを使用してAA Web APIを使用してレコードを挿入し、SQLServerにデータを投稿する方法を紹介します。このセッションでは、WebAPIによるgetおよびpost操作を確認できます。別の言い方をすれば、ボタンクリックイベントを使用してレコードを挿入および取得すると言えます。

このセッションを行う前に、前のセッションにアクセスしてください。

従うべきステップ、

ステップ1

HTTPクライアントを使用してデータを取得するためのビューを取得するための新しいアクションを(MVCクライアントアプリケーションの)HomeControllerに追加します。

コード参照

public ActionResult Part4()   
        {  
            List<Employee> list = new List<Employee>();  
            HttpClient client = new HttpClient();  
            var result = client.GetAsync("http://localhost:47250/api/satya").Result;  
            if (result.IsSuccessStatusCode)  
            {  
                list = result.Content.ReadAsAsync<List<Employee>>().Result;  
                ViewBag.userdetails = list;  
            }  
            return View();  
        } 

コードの説明


 

ページの初期ロード中にテーブルデータが表示されます。これは、データがHttpClientを使用する入力コントロールを使用してテーブルにバインドされることを意味します。[HttpGet]を使用したこのコントローラーアクションメソッド。

ステップ2

HTTPクライアントを使用した投稿データのHomeController(MVCクライアントアプリケーション内)に対して同じアクションを使用します。

コード参照

[HttpPost]  
    public ActionResult Part4(Employee emp)   
    {  
        if (ModelState.IsValid)  
        {  
            HttpClient client = new HttpClient();  
            var result = client.PostAsJsonAsync("http://localhost:47250/api/satya", emp).Result;  
            if (result.IsSuccessStatusCode)  
            {  
                emp = result.Content.ReadAsAsync<Employee>().Result;  
                ViewBag.Result = "Data Is Successfully Saved!";  
                List<Employee> list = new List<Employee>();  
                HttpClient client1 = new HttpClient();  
                var result1 = client1.GetAsync("http://localhost:47250/api/satya").Result;  
                if (result1.IsSuccessStatusCode)  
                {  
                    list = result1.Content.ReadAsAsync<List<Employee>>().Result;  
                    ViewBag.userdetails = list;  
                }  
                ModelState.Clear();  
                return View(new Employee());  
            }  
            else  
            {  
                ViewBag.Result = "Error! Please try with valid data.";  
            }  
        }  
        return View(emp);  
    } 

コードの説明

この部分では、フォームのPOSTメソッドまたはボタンクリックイベントの後、データ挿入とテーブルデータが表示されます。サイドポストセクションでは、データ取得のためのsoemthingを追加しました。そうしないと、オブジェクト参照がオブジェクトのインスタンスに設定されていないというエラーが発生します。この問題については、注のビューセクションで説明します。

  1. List <Employee> list =  new  List <Employee>();  
                    HttpClient client1 = new HttpClient();  
                    var result1 = client1.GetAsync("http://localhost:47250/api/satya").Result;  
                    if (result1.IsSuccessStatusCode)  
                    {  
                        list = result1.Content.ReadAsAsync<List<Employee>>().Result;  
                        ViewBag.userdetails = list;  
                    } 

モデルの状態とモデルバインディング検証の状態を含むモデル状態ディクショナリオブジェクトは、モデル状態ディクショナリからすべてのアイテムを削除します。

ModelState.Clear(); 

ステップ3

アクションメソッドを右クリックします(ここではフォームPart4()を右クリックします)>ビューの追加...>[強く型付けされたビューの作成]をオンにします>モデルクラスを選択します>>追加します。ここでのモデルクラスは「従業員(エンティティ)」です。

 

コード参照

@model Entities.Employee  
  
@{  
    ViewBag.Title = "Satyaprakash - Post data to Web API using HTTPClient (in MVC client application) With Validation";  
}  
  
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">  
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>  
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>  
  
  
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/4.4.0/bootbox.min.js">  
  
</script>  
  
<style>  
    span.field-validation-error {  
        color: red;  
    }  
  
    table {  
        font-family: arial, sans-serif;  
        border-collapse: collapse;  
        width: 100%;  
    }  
  
    td, th {  
        border: 1px solid #dddddd;  
        text-align: left;  
        padding: 8px;  
    }  
  
    tr:nth-child(even) {  
        background-color: #dddddd;  
    }  
  
    .button {  
        background-color: #4CAF50;  
        border: none;  
        color: white;  
        padding: 15px 32px;  
        text-align: center;  
        text-decoration: none;  
        display: inline-block;  
        font-size: 16px;  
        margin: 4px 2px;  
        cursor: pointer;  
    }  
  
    .button4 {  
        border-radius: 9px;  
    }  
</style>  
  
  
<div style="padding:10px ; align-content:center">  
    <fieldset>  
        <legend style="font-family:Arial Black;color:blue">Post data to Web API using HTTPClient (in MVC client application) With Validation</legend>  
    </fieldset>  
</div>  
  
  
<div style="max-width:600px;">  
    @using (Html.BeginForm("Part4", "Home", FormMethod.Post, new { role = "form" }))  
    {  
        @Html.ValidationSummary(true)  
  
        <div class="form-group">  
            @Html.LabelFor(a => a.FirstName)  
            @Html.TextBoxFor(a => a.FirstName, new { @class = "form-control" })  
            @Html.ValidationMessageFor(a => a.FirstName)  
        </div>  
        <div class="form-group">  
            @Html.LabelFor(a => a.LastName)  
            @Html.TextBoxFor(a => a.LastName, new { @class = "form-control" })  
            @Html.ValidationMessageFor(a => a.LastName)  
        </div>  
        <div class="form-group">  
            @Html.LabelFor(a => a.EmailID)  
            @Html.TextBoxFor(a => a.EmailID, new { @class = "form-control" })  
            @Html.ValidationMessageFor(a => a.EmailID)  
        </div>  
        <div class="form-group">  
            @Html.LabelFor(a => a.City)  
            @Html.TextBoxFor(a => a.City, new { @class = "form-control" })  
            @Html.ValidationMessageFor(a => a.City)  
        </div>  
        <div class="form-group">  
            @Html.LabelFor(a => a.Country)  
            @Html.TextBoxFor(a => a.Country, new { @class = "form-control" })  
            @Html.ValidationMessageFor(a => a.Country)  
        </div>  
        <input id="btn" type="submit" value="Create" class="button button4" />  
  
        <div style="width:90%; padding:10px; margin:0 auto;">  
            @if (ViewBag.Result != null)  
            {  
                @*<div style="color:red">@ViewBag.Result</div>*@  
  
                <script>  
                    $(document).ready(function () {  
                        $('#btn').click(function () {  
                            $('#tableshow').hide();  
                        });  
  
                        bootbox.alert('@ViewBag.Result');  
                        $('#tableshow').show();  
                    });  
                </script>  
            }  
        </div>  
    }  
</div>  
  
@*System.NullReferenceException , Object reference not set to an instance of an object. This error due to without added for data retrieve comment line code in Part4() in homecontroller in webapplication*@  
<div id="tableshow" style="width:90%; padding:10px; margin:0 auto;">  
    <table class="table table-responsive table-striped table-bordered">  
        <thead>  
            <tr>  
                <th style="background-color: Yellow;color: blue">Full Name</th>  
                <th style="background-color: Yellow;color: blue">Email</th>  
                <th style="background-color: Yellow;color: blue">City</th>  
                <th style="background-color: Yellow;color: blue">Country</th>  
            </tr>  
        </thead>  
        <tbody>  
            @foreach (var i in ViewBag.userdetails)   
            {  
                <tr>  
                    <td>@i.FirstName @i.LastName</td>  
                    <td>@i.EmailID</td>  
                    <td>@i.City</td>  
                    <td>@i.Country</td>  
                </tr>  
            }  
        </tbody>  
    </table>  
</div>  
@*System.NullReferenceException , Object reference not set to an instance of an object.*@  
  
@section Scripts{  
    @Scripts.Render("~/bundles/jqueryval")  
} 

コードの説明

フォームポストメソッド内のこのコードセクションにスクリプトを追加して、ボタンクリック中にイベントテーブルデータが表示されるようにしました。

<div style="width:90%; padding:10px; margin:0 auto;">  
            @if (ViewBag.Result != null)  
            {  
                @*<div style="color:red">@ViewBag.Result</div>*@  
  
                <script>  
                    $(document).ready(function () {  
                        $('#btn').click(function () {  
                            $('#tableshow').hide();  
                        });  
  
                        bootbox.alert('@ViewBag.Result');  
                        $('#tableshow').show();  
                    });  
                </script>  
            }  
        </div> 

ここでは、ブートボックスライブラリを使用してアラート通知を表示しました。ViewBag.Resultには、コントローラーアクションメソッドのメッセージが含まれています。

bootbox.alert('@ViewBag.Result'); 

ノート 

このセッション中に、System.NullReferenceExceptionに関する問題が発生しました。オブジェクト参照が、オブジェクトのインスタンスに設定されていません。

そこで、Part4()コントローラーアクションメソッドのpostメソッドで説明されているように、iIはdiv idを作成し、スクリプトセクション内に配置しました。このエラーは、MVCクライアントアプリケーションのホームコントローラーのPart4()にデータ取得コメント行コードのデータが追加されていないことが原因でした。

<div id="tableshow" style="width:90%; padding:10px; margin:0 auto;">  
    <table class="table table-responsive table-striped table-bordered">  
        <thead>  
            <tr>  
                <th style="background-color: Yellow;color: blue">Full Name</th>  
                <th style="background-color: Yellow;color: blue">Email</th>  
                <th style="background-color: Yellow;color: blue">City</th>  
                <th style="background-color: Yellow;color: blue">Country</th>  
            </tr>  
        </thead>  
        <tbody>  
            @foreach (var i in ViewBag.userdetails)   
            {  
                <tr>  
                    <td>@i.FirstName @i.LastName</td>  
                    <td>@i.EmailID</td>  
                    <td>@i.City</td>  
                    <td>@i.Country</td>  
                </tr>  
            }  
        </tbody>  
    </table>  
</div> 

出力

ページ読み込みイベント中。

 

モバイルビューのサポート。

 

出力についてよりよく理解するためのGIF画像。

 

上の画像に示すように、SQLサーバーでレコードの挿入を確認してください。

 

ソースコードへのリンク

まとめ

  • HTTPクライアントを使用したフォームコントロール検証でデータを取得および投稿します。
     
  • アラートメッセージ用のブートボックスjavascriptライブラリ。
  • モバイルレスポンシブサポート。

前の部分-

パート1- MVCとエンティティフレームワークを使用したASP.NETWebAPI

パート2-データを取得するためにMVC、エンティティフレームワーク、jQueryを使用するASP.NET Web API 

パート3- ASP.NETWebAPIでクラスライブラリを使用して、エンティティデータモデル(.edmx)のモデルクラスを複数のプロジェクトに再利用する

パート4- 

データを取得するためにMVC、Entity Framework、およびHttpClientを使用するASP.NET Web API

パート5-検証付きの取得と投稿にMVC、Entity Framework、jQueryを使用したASP.NET Web API  

ソース:https ://www.c-sharpcorner.com/article/asp-net-web-api-using-mvc-entity-framework-and-httpclient-for-get-and-post-with/

#aspdotnet #mvc #entity-framework 

HttpClientを使用してAAWebAPIを使用してレコードを挿入し、SQLでデータを投稿します
Diego  Elizondo

Diego Elizondo

1648044960

Arquitectura Limpia Con .NET 6 Utilizando Entity Framework

Este artículo es una continuación de mi artículo anterior,  Arquitectura limpia con .NET 6 . En el artículo anterior, he elaborado sobre arquitectura limpia, principios y consideraciones de diseño. Además, he creado una solución completa de arquitectura limpia con .NET 6 y ASP.NET Web API.

Para saber acerca de la arquitectura limpia, consulte  este artículo  donde he aclarado los siguientes puntos.

  • ¿Qué es la arquitectura limpia?
  • Principios básicos de la arquitectura limpia
  • Diagrama de arquitectura limpia
  • Capas de arquitectura limpia
  • Muestra de diseño

Además, he diseñado una solución de arquitectura limpia con .NET 6 y ASP.NET Core Web API .

  • Diseñe una arquitectura limpia con .NET 6
  • API web principal de ASP.NET con arquitectura limpia

El alcance de este artículo es implementar Entity Framework en Clean Architecture con .NET 6 y ASP.NET core Web API.

  • Implementar Entity Framework en una solución de arquitectura limpia con .NET 6
  • Implementar un caso de negocio
  • Diseñe ASP.NET Core Web API con operación CRUD

Hemos creado una solución de arquitectura limpia como se muestra con .NET 6.

  • No habrá ninguna referencia a la biblioteca de dominios.
  • Aplicación: Agregar referencia del proyecto de Dominio
  • Infraestructura: Agregar referencia del proyecto de aplicación
  • WebApi: Agregar referencia de aplicaciones y proyectos de Infraestructura

Implementemos un caso de negocio.

Crearemos una Configuración de la aplicación donde podemos almacenar algunas variables y configuraciones de la aplicación, como detalles de SMTP, datos de la aplicación, etc.

La entidad está en el centro de la arquitectura limpia, por lo tanto; Comenzaremos con la creación de la entidad. Creamos una entidad AppSetting en la biblioteca de dominio como se muestra.

Agreguemos una entidad base con propiedades de Id en la carpeta común como se muestra.

Arquitectura limpia con .NET 6 utilizando Entity Framework

Mantenemos todas las propiedades comunes en esta  clase abstracta BaseEntity. La razón es reutilizar eso en cada entidad. 

BaseEntity.cs

namespace Domain.Common
{
    public abstract class BaseEntity<T>
    {
        public virtual T Id { get; set; }
    }
}

C#

También puede incluir algunas otras propiedades, sin embargo, para simplificar, solo conservo Id.

El uso del tipo T le dará la opción de hacer que la identificación sea dinámica. Por ejemplo, podemos mantener Id como int, bigInt o Guid según los requisitos de la tabla.

Ahora, crearemos una  entidad AppSetting  en la carpeta Master. Se recomienda agrupar la entidad en función de los casos de uso y guardarla en la carpeta correspondiente.

Arquitectura limpia con .NET 6 utilizando Entity Framework

AppSetting.cs

global using Domain.Common;

namespace Domain.Master
{
    public class AppSetting : BaseEntity<int>
    {
        /// <summary>
        /// Gets or sets the ReferenceKey
        /// </summary>
        public string ReferenceKey { get; set; } = String.Empty;
        /// <summary>
        /// Gets or sets the Value
        /// </summary>
        public string Value { get; set; } = String.Empty;
        /// <summary>
        /// Gets or sets the Description
        /// </summary>
        public string Description { get; set; } = String.Empty;
        /// <summary>
        /// Gets or sets the Type
        /// </summary>
        public string Type { get; set; } = String.Empty;
    }
}

C#

Aquí, hemos heredado la entidad base, por lo tanto, no necesitamos agregar la propiedad Id y hemos declarado el tipo int de Id.

Además, he usado  el uso global ,  que es una característica  de .NET 6  , por lo que no necesito agregar una referencia de la entidad base en otras entidades.

Vayamos a la biblioteca de aplicaciones. Esta biblioteca contiene toda la lógica comercial como servicios, interfaces, validaciones de dominio, manejo de errores, etc. Para limitar el alcance de este artículo, agregaré una interfaz para el contexto de la aplicación y un servicio solo en esta biblioteca de aplicaciones. 

Implementando Entity Framework en Arquitectura Limpia

Implementemos un marco de entidad en nuestra solución. Usaré un marco de entidad con el servidor MS SQL. Necesitamos agregar los siguientes paquetes a las respectivas bibliotecas y proyectos.

Paquetes para la  biblioteca de aplicaciones .

Microsoft.EntityFramework.Core

Microsoft.Extensions.DependencyInjection.Abstractions

Newtonsoft.Json

Paquetes para   Biblioteca de Infraestructura .

Microsoft.EntityFrameworkCore.Diseño

Microsoft.EntityFrameworkCore.SqlServer

Microsoft.EntityFrameworkCore.Herramientas

Microsoft.Extensions.DependencyInjection.Abstractions

Paquetes para  Web API

Microsoft.EntityFrameworkCore.Diseño

Podemos instalar estos paquetes en los proyectos respectivos usando el comando o desde la GUI como se muestra a continuación. 

Install-Package Microsoft.EntityFramework.Core -ProjectName Application

JavaScript

Arquitectura limpia con .NET 6 utilizando Entity Framework

Así mismo, podemos instalar otros paquetes.

Continuaremos creando una interfaz para el contexto de la aplicación en el proyecto de la aplicación en la carpeta común como se indica a continuación.

Arquitectura limpia con .NET 6 utilizando Entity Framework

IApplicationDBContext.cs

using Domain.Master;
using Microsoft.EntityFrameworkCore;

namespace Application.Common.Interfaces
{
    public interface IApplicationDBContext
    {
        DbSet<AppSetting> AppSettings { get; set; }
        Task<int> SaveChangesAsync();
    }
}

C#

Según el principio de arquitectura limpia, agregaremos una interfaz para el contexto de la aplicación en la parte central de la lógica comercial (aplicación); sin embargo, la implementaremos en la infraestructura basada en la base de datos porque queremos mantener a los agentes externos fuera de la lógica central. Procedamos creando un contexto de aplicación, que será una implementación de la interfaz anterior.

Aquí nuevamente, organizaremos el proyecto como se muestra y crearemos una clase de contexto de aplicación.

Crearemos una clase  AppicationDBContext  en la carpeta de persistencia y  heredaremos DBContext  e  IApplicationDBContext  como se muestra a continuación.

Arquitectura limpia con .NET 6 utilizando Entity Framework

Podemos implementar  la interfaz IApplicationDBContext  agregando  DbSet  de  AppSetting SaveChangesAsync .

ApplicationDBContext.cs

using Application.Common.Interfaces;
using Domain.Master;
using Microsoft.EntityFrameworkCore;

namespace Infrastructure.Persistence
{
    public class ApplicationDBContext : DbContext, IApplicationDBContext
    {
        #region Ctor
        public ApplicationDBContext(DbContextOptions<ApplicationDBContext> options)
         : base(options)
        {
        }
        #endregion
        #region DbSet
        public DbSet<AppSetting> AppSettings { get; set; }
        #endregion
        #region Methods
        public Task<int> SaveChangesAsync()
        {
            return base.SaveChangesAsync();
        }
        #endregion

    }
}

C#

Ahora agregaremos una clase de inyección de dependencia en la biblioteca de Infraestructura como se muestra.

Arquitectura limpia con .NET 6 utilizando Entity Framework

Permítanme explicar la clase con más detalles.

services.AddDbContext<ApplicationDBContext>(options =>
                options.UseSqlServer(configuration.GetConnectionString("RijsatDatabase"),
                b => b.MigrationsAssembly(typeof(ApplicationDBContext).Assembly.FullName)), ServiceLifetime.Transient);

C#

Agregamos arriba para probar la cadena de conexión, y estamos usando MSSQL Server. Obtenemos este valor mediante  ICongifuration  porque insertaremos la cadena de conexión en  AppSetting.cs  del host de API web.

services.AddScoped<IApplicationDBContext>(provider => provider.GetService<ApplicationDBContext>());

C#

Este es el proveedor de  IApplicationDBContext  en  ApplicationDBContext.cs  , es decir, inyección de dependencia.

DependencyInjection.cs

using Application.Common.Interfaces;
using Infrastructure.Persistence;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace Infrastructure
{
    public static class DependencyInjection
    {
        public static IServiceCollection AddPersistence(this IServiceCollection services,
            IConfiguration configuration)
        {
            services.AddDbContext<ApplicationDBContext>(options =>
                options.UseSqlServer(configuration.GetConnectionString("RijsatDatabase"),
                b => b.MigrationsAssembly(typeof(ApplicationDBContext).Assembly.FullName)), ServiceLifetime.Transient);

            services.AddScoped<IApplicationDBContext>(provider => provider.GetService<ApplicationDBContext>());
            return services;
        }
    }
}

C#

Necesitamos agregar la cadena de conexión en  AppSetting.json  del proyecto host de Web API como se indica a continuación.

Arquitectura limpia con .NET 6 utilizando Entity Framework

Proporcione la cadena de conexión según su base de datos.

"ConnectionStrings": {
    "RijsatDatabase": "Data Source=rijwan7475001;Initial Catalog=RijsatDb;Integrated Security=True;Connect Timeout=60;TrustServerCertificate=True"
  }

JavaScript

Además, tenemos que hacer una entrada de inyección de dependencia en la llamada de servicio del  archivo program.cs  (inicio) como se muestra.

Arquitectura limpia con .NET 6 utilizando Entity Framework

Haremos la entrada del servicio en  IServiceCollection  antes del creador de la aplicación.

//Dependency Injection
builder.Services.AddPersistence(builder.Configuration);

C#

Estamos listos con la implementación de Entity Framework en Clean Architecture con .NET 6.

Ejecutemos el comando de migración en la consola del administrador de paquetes.

Add-Migration "DB Initialize"

C#

Arquitectura limpia con .NET 6 utilizando Entity Framework

Asegúrese de haber seleccionado el  proyecto de infraestructura como predeterminado  y  la API web como proyecto de inicio .

Arquitectura limpia con .NET 6 utilizando Entity Framework

Update-Database

BÁSICO

Arquitectura limpia con .NET 6 utilizando Entity Framework

Hemos implementado con éxito un marco de entidad en nuestra solución. La base de datos se crea como se esperaba.

En este artículo, implementamos con éxito un marco de entidad en Clean Architecture con .NET 6 y ASP.NET core Web API.

En el próximo artículo, haremos una operación CRUD completa, crearemos API web y probaremos con swagger.

Conclusión

En este artículo, he demostrado paso a paso cómo implementar un marco de entidad en una arquitectura limpia con .NET 6 y ASP.Net core web API. Además, creé un modelo y creé una base de datos usando el comando de migración de la base de datos EF. En el próximo artículo, demostraré una operación CRUD utilizando el marco de entidad en Clean Architecture con .NET 6.

Fuente: https://www.c-sharpcorner.com/article/clean-architecture-with-net-6-using-entity-framework/

#dotnet  #entity-framework 

Arquitectura Limpia Con .NET 6 Utilizando Entity Framework
伊藤  直子

伊藤 直子

1648044780

EntityFrameworkを使用した.NET6によるクリーンなアーキテクチャ

この記事は、前回の記事「  .NET6を使用したクリーンアーキテクチャ」の続きです。前回の記事では、クリーンなアーキテクチャ、原則、および設計上の考慮事項について詳しく説明しました。さらに、.NET6とASP.NETWebAPIを使用して完全なクリーンアーキテクチャソリューションを作成しました。

クリーンなアーキテクチャについて知るため  に、私が以下の点を解明したこの記事をチェックしてください。

  • クリーンアーキテクチャとは
  • クリーンアーキテクチャの基本原則
  • クリーンなアーキテクチャ図
  • クリーンなアーキテクチャのレイヤー
  • デザインサンプル

さらに、  .NET6とASP.NETCoreWebAPIを使用してクリーンなアーキテクチャソリューションを設計しました。

  • .NET6を使用してクリーンなアーキテクチャを設計する
  • クリーンアーキテクチャを使用したASP.NETコアWebAPI

この記事の範囲は、.NET6およびASP.NETコアWebAPIを使用してCleanArchitectureにEntityFrameworkを実装することです。

  • .NET6を使用したCleanArchitectureSolutionにEntityFrameworkを実装する
  • ビジネスケースを実装する
  • CRUD操作を使用してASP.NETCoreWebAPIを設計する

.NET 6で示すように、クリーンなアーキテクチャソリューションを作成しました。

  • ドメインライブラリへの参照はありません
  • アプリケーション:ドメインプロジェクトの参照を追加
  • インフラストラクチャ:アプリケーションプロジェクトの参照を追加
  • WebApi:アプリケーションおよびインフラストラクチャプロジェクトの参照を追加します

ビジネスケースを実装しましょう。

SMTPの詳細、アプリケーションデータなど、いくつかのアプリケーション変数と構成を保存できるアプリケーション設定を作成します。

したがって、エンティティはクリーンなアーキテクチャの中心にあります。エンティティの作成から始めます。図のように、ドメインライブラリにエンティティAppSettingを作成します。

図のように、共通フォルダーの下にIdプロパティを持つベースエンティティを追加しましょう。

EntityFrameworkを使用した.NET6によるクリーンなアーキテクチャ

この BaseEntity抽象クラスにすべての共通プロパティを保持します。 その理由は、それをすべてのエンティティで再利用するためです。 

BaseEntity.cs

namespace Domain.Common{    public abstract class BaseEntity<T>    {        public virtual T Id { get; set; }    }}

C#

他のいくつかのプロパティを含めることもできますが、簡単にするために、IDのみを保持しています。

Tタイプを使用すると、Idを動的にするオプションが提供されます。たとえば、テーブルの要件に基づいて、Idをint、bigInt、またはGuidとして保持する場合があります。

次に、 MasterフォルダーにAppSetting エンティティを作成し ます。ユースケースに基づいてエンティティをグループ化し、関連するフォルダの下に保持することをお勧めします。

EntityFrameworkを使用した.NET6によるクリーンなアーキテクチャ

AppSetting.cs

global using Domain.Common;namespace Domain.Master{    public class AppSetting : BaseEntity<int>    {        /// <summary>        /// Gets or sets the ReferenceKey        /// </summary>        public string ReferenceKey { get; set; } = String.Empty;        /// <summary>        /// Gets or sets the Value        /// </summary>        public string Value { get; set; } = String.Empty;        /// <summary>        /// Gets or sets the Description        /// </summary>        public string Description { get; set; } = String.Empty;        /// <summary>        /// Gets or sets the Type        /// </summary>        public string Type { get; set; } = String.Empty;    }}

C#

ここでは、基本エンティティを継承しているため、Idプロパティを追加する必要はなく、intタイプのIdを宣言しています。

さらに、   .NET 6 の機能であるグローバル使用を使用した ため、他のエンティティにベースエンティティの参照を追加する必要はありません。

アプリケーションライブラリに移動してみましょう。このライブラリには、サービス、インターフェイス、ドメイン検証、エラー処理などのすべてのビジネスロジックが含まれています。この記述の範囲を制限するために、このアプリケーションライブラリの下にのみアプリケーションコンテキストとサービスのインターフェイスを追加します。 

クリーンアーキテクチャでのEntityFrameworkの実装

ソリューションにエンティティフレームワークを実装しましょう。MSSQLサーバーでエンティティフレームワークを使用します。以下のパッケージをそれぞれのライブラリとプロジェクトに追加する必要があります。

アプリケーションライブラリのパッケージ 。

Microsoft.EntityFramework.Core

Microsoft.Extensions.DependencyInjection.Abstractions

Newtonsoft.Json

インフラストラクチャ ライブラリのパッケージ 。

Microsoft.EntityFrameworkCore.Design

Microsoft.EntityFrameworkCore.SqlServer

Microsoft.EntityFrameworkCore.Tools

Microsoft.Extensions.DependencyInjection.Abstractions

WebAPIのパッケージ 

Microsoft.EntityFrameworkCore.Design

これらのパッケージは、以下に示すように、コマンドまたはGUIからそれぞれのプロジェクトにインストールできます。 

Install-Package Microsoft.EntityFramework.Core -ProjectName Application

JavaScript

EntityFrameworkを使用した.NET6によるクリーンなアーキテクチャ

同様に、他のパッケージをインストールすることもできます。

次に、以下に示すように、共通フォルダーの下のアプリケーションプロジェクトにアプリケーションコンテキストのインターフェイスを作成します。

EntityFrameworkを使用した.NET6によるクリーンなアーキテクチャ

IApplicationDBContext.cs

using Domain.Master;using Microsoft.EntityFrameworkCore;namespace Application.Common.Interfaces{    public interface IApplicationDBContext    {        DbSet<AppSetting> AppSettings { get; set; }        Task<int> SaveChangesAsync();    }}

C#

クリーンなアーキテクチャの原則に従って、ビジネスロジック(アプリケーション)コア部分にアプリケーションコンテキストのインターフェイスを追加しますが、外部エージェントをコアロジックの外に置きたいため、データベースに基づいてインフラストラクチャに実装します。上記のインターフェースの実装となるアプリケーションコンテキストを作成してみましょう。

ここでも、示されているようにプロジェクトを編成し、アプリケーションコンテキストクラスを作成します。

 以下に示すように、persistenceフォルダーの下に クラス AppicationDBContextを作成し、 DBContext と IApplicationDBContext を継承します。

EntityFrameworkを使用した.NET6によるクリーンなアーキテクチャ

AppSetting の DbSet と SaveChangesAsyncを追加することで、 IApplicationDBContext インターフェイス を実装でき ます。

ApplicationDBContext.cs

using Application.Common.Interfaces;using Domain.Master;using Microsoft.EntityFrameworkCore;namespace Infrastructure.Persistence{    public class ApplicationDBContext : DbContext, IApplicationDBContext    {        #region Ctor        public ApplicationDBContext(DbContextOptions<ApplicationDBContext> options)         : base(options)        {        }        #endregion        #region DbSet        public DbSet<AppSetting> AppSettings { get; set; }        #endregion        #region Methods        public Task<int> SaveChangesAsync()        {            return base.SaveChangesAsync();        }        #endregion    }}

C#

次に、図のようにインフラストラクチャライブラリに依存性注入クラスを追加します。

EntityFrameworkを使用した.NET6によるクリーンなアーキテクチャ

クラスについて詳しく説明します。

services.AddDbContext<ApplicationDBContext>(options =>                options.UseSqlServer(configuration.GetConnectionString("RijsatDatabase"),                b => b.MigrationsAssembly(typeof(ApplicationDBContext).Assembly.FullName)), ServiceLifetime.Transient);

C#

接続文字列を証明するために上記を追加し、MSSQLServerを使用しています。接続文字列をWebAPIホストのAppSetting.csに挿入するため、  ICongifuration を使用してこの値を取得してい  ます。

services.AddScoped<IApplicationDBContext>(provider => provider.GetService<ApplicationDBContext>());

C#

これは、 ApplicationDBContext.csへ のIApplicationDBContext のプロバイダー、  つまり依存性注入です。

DependencyInjection.cs

using Application.Common.Interfaces;using Infrastructure.Persistence;using Microsoft.EntityFrameworkCore;using Microsoft.Extensions.Configuration;using Microsoft.Extensions.DependencyInjection;namespace Infrastructure{    public static class DependencyInjection    {        public static IServiceCollection AddPersistence(this IServiceCollection services,            IConfiguration configuration)        {            services.AddDbContext<ApplicationDBContext>(options =>                options.UseSqlServer(configuration.GetConnectionString("RijsatDatabase"),                b => b.MigrationsAssembly(typeof(ApplicationDBContext).Assembly.FullName)), ServiceLifetime.Transient);            services.AddScoped<IApplicationDBContext>(provider => provider.GetService<ApplicationDBContext>());            return services;        }    }}

C#

 以下に示すように、WebAPIホストプロジェクトのAppSetting.jsonに接続文字列を追加する必要があり ます。

EntityFrameworkを使用した.NET6によるクリーンなアーキテクチャ

データベースに従って接続文字列を指定します。

"ConnectionStrings": {    "RijsatDatabase": "Data Source=rijwan7475001;Initial Catalog=RijsatDb;Integrated Security=True;Connect Timeout=60;TrustServerCertificate=True"  }

JavaScript

さらに、示されているように、 program.cs  (スタートアップ)ファイルのサービス呼び出しに依存性注入のエントリを作成する必要があり ます。

EntityFrameworkを使用した.NET6によるクリーンなアーキテクチャ

アプリビルダーの前に、 IServiceCollection の下にサービスのエントリを作成し ます。

//Dependency Injectionbuilder.Services.AddPersistence(builder.Configuration);

C#

.NET6を使用したCleanArchitectureでのEntityFrameworkの実装の準備が整いました。

パッケージマネージャーコンソールで移行コマンドを実行してみましょう。

Add-Migration "DB Initialize"

C#

EntityFrameworkを使用した.NET6によるクリーンなアーキテクチャ

インフラストラクチャプロジェクトをデフォルトとして選択し 、  WebAPIをスタートアッププロジェクトとして選択していることを確認してください 。

EntityFrameworkを使用した.NET6によるクリーンなアーキテクチャ

Update-Database

ベーシック

EntityFrameworkを使用した.NET6によるクリーンなアーキテクチャ

ソリューションにEntityFrameworkを正常に実装しました。データベースは期待どおりに作成されます。

この記事では、.N  ET6とASP.NETCoreWebAPIを使用してCleanArchitectureにエンティティフレームワークを正常に実装しました。

次の記事では、完全なCRUD操作を実行し、Web APIを構築し、Swaggerでテストします。

結論

この記事では、.NET6とASP.NetコアWebAPIを使用してクリーンなアーキテクチャでエンティティフレームワークを実装する方法を段階的に説明しました。さらに、EFデータベース移行コマンドを使用してモデルを作成し、データベースを作成しました。次の記事では、.NET6を使用したCleanArchitectureでエンティティフレームワークを使用したCRUD操作について説明します。

ソース:https ://www.c-sharpcorner.com/article/clean-architecture-with-net-6-using-entity-framework/

#dotnet  #entity-framework  

EntityFrameworkを使用した.NET6によるクリーンなアーキテクチャ

Restringir La Eliminación Del Registro De Entidad

Requisito

El permiso tiene búsqueda de tipo de permiso.

El tipo de permiso tiene el campo "Tipo" con las opciones manzana, naranja.

Ahora, cuando se elimina el registro de permiso, debe verificar el valor de Tipo en Tipo de permiso y, si es naranja, no solo permita la eliminación de un registro. De lo contrario, no se debe eliminar un registro con el complemento.

Código del complemento

 

using Microsoft.Xrm.Sdk;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Microsoft.Crm.Sdk.Samples
{
    public class RestrictPermitDelete : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {

            //Extract the tracing service for use in debugging sandboxed plug-ins.
            ITracingService tracingService =
                (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            // Obtain the execution context from the service provider.
            IPluginExecutionContext context = (IPluginExecutionContext)
                serviceProvider.GetService(typeof(IPluginExecutionContext));

            // Obtain the organization service reference.
            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

            //<snippetFollowupPlugin2>
            // The InputParameters collection contains all the data passed in the message request.
            if (context.InputParameters.Contains("Target") &&
                context.InputParameters["Target"] is EntityReference)
            {
                // Obtain the target entity from the input parameters.
                EntityReference entity = (EntityReference)context.InputParameters["Target"];
                //</snippetFollowupPlugin2>

                // Verify that the target entity represents an contoso_permit.
                // If not, this plug-in was not registered correctly.
                if (entity.LogicalName != "contoso_permit")
                    return;

                // Get Lookup field value
                Entity permitEntity = service.Retrieve("contoso_permit", entity.Id, new Xrm.Sdk.Query.ColumnSet("contoso_permittype"));
                if (permitEntity != null)
                {
                    if (permitEntity.Attributes.Contains("contoso_permittype") && permitEntity.Attributes["contoso_permittype"] != null)
                    {
                        EntityReference permitType = (EntityReference)permitEntity.Attributes["contoso_permittype"];
                        if (permitType != null && permitType.Id != Guid.Empty)
                        {
                            Entity permitTypeEntity = service.Retrieve("contoso_permittype", permitType.Id, new Xrm.Sdk.Query.ColumnSet("contoso_type"));
                            if (permitTypeEntity != null)
                            {
                                if (permitTypeEntity.Attributes.Contains("contoso_type") && permitTypeEntity.Attributes["contoso_type"] != null)
                                {
                                    OptionSetValue type = (OptionSetValue)permitTypeEntity.Attributes["contoso_type"];
                                    if (type != null && type.Value == 100000001)//100000001 - Orange Value
                                    {
                                        throw new InvalidPluginExecutionException("Permit Can not be Deleted as Permit Type is Orange");
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

Registre el paso del complemento como se muestra a continuación,

 

Restringir la eliminación del registro de entidad según el valor del campo principal

 

Ahora, cuando el usuario intenta eliminar el registro de permiso cuyo tipo de permiso es naranja, el sistema lanzará una excepción como se muestra a continuación,

 

Restringir la eliminación del registro de entidad según el valor del campo principal

 

Nota:
Podemos lograr el mismo requisito con el flujo de trabajo en tiempo real, pero quería mostrar cómo se puede lograr con el complemento.

¡Espero que esto ayude! 

Enlace: https://www.c-sharpcorner.com/blogs/dataverse-restrict-delete-of-entity-record-based-on-parent-field-val

#entity 

Restringir La Eliminación Del Registro De Entidad

親フィールド値に基づいてエンティティレコードの削除を制限する

要件

許可には、許可タイプのルックアップがあります。

許可タイプには、オプションがアップル、オレンジの「タイプ」フィールドがあります。

ここで、許可レコードが削除された場合、許可タイプのタイプの値を確認する必要があります。オレンジ色の場合は、レコードの削除のみを許可しないでください。それ以外の場合は、プラグインを使用してレコードを削除しないでください。

プラグインコード

 

using Microsoft.Xrm.Sdk;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Microsoft.Crm.Sdk.Samples
{
    public class RestrictPermitDelete : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {

            //Extract the tracing service for use in debugging sandboxed plug-ins.
            ITracingService tracingService =
                (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            // Obtain the execution context from the service provider.
            IPluginExecutionContext context = (IPluginExecutionContext)
                serviceProvider.GetService(typeof(IPluginExecutionContext));

            // Obtain the organization service reference.
            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

            //<snippetFollowupPlugin2>
            // The InputParameters collection contains all the data passed in the message request.
            if (context.InputParameters.Contains("Target") &&
                context.InputParameters["Target"] is EntityReference)
            {
                // Obtain the target entity from the input parameters.
                EntityReference entity = (EntityReference)context.InputParameters["Target"];
                //</snippetFollowupPlugin2>

                // Verify that the target entity represents an contoso_permit.
                // If not, this plug-in was not registered correctly.
                if (entity.LogicalName != "contoso_permit")
                    return;

                // Get Lookup field value
                Entity permitEntity = service.Retrieve("contoso_permit", entity.Id, new Xrm.Sdk.Query.ColumnSet("contoso_permittype"));
                if (permitEntity != null)
                {
                    if (permitEntity.Attributes.Contains("contoso_permittype") && permitEntity.Attributes["contoso_permittype"] != null)
                    {
                        EntityReference permitType = (EntityReference)permitEntity.Attributes["contoso_permittype"];
                        if (permitType != null && permitType.Id != Guid.Empty)
                        {
                            Entity permitTypeEntity = service.Retrieve("contoso_permittype", permitType.Id, new Xrm.Sdk.Query.ColumnSet("contoso_type"));
                            if (permitTypeEntity != null)
                            {
                                if (permitTypeEntity.Attributes.Contains("contoso_type") && permitTypeEntity.Attributes["contoso_type"] != null)
                                {
                                    OptionSetValue type = (OptionSetValue)permitTypeEntity.Attributes["contoso_type"];
                                    if (type != null && type.Value == 100000001)//100000001 - Orange Value
                                    {
                                        throw new InvalidPluginExecutionException("Permit Can not be Deleted as Permit Type is Orange");
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

以下に示すようにプラグインステップを登録します。

 

親フィールドの値に基づいてエンティティレコードの削除を制限する

 

これで、ユーザーが許可タイプがオレンジの許可レコードを削除しようとすると、システムは次のように例外をスローします。

 

親フィールドの値に基づいてエンティティレコードの削除を制限する

 


リアルタイムワークフローを使用して同じ要件を達成できますが、プラグインを使用してどのように達成できるかを示したいと思いました。

お役に立てれば! 

リンク:https//www.c-sharpcorner.com/blogs/dataverse-restrict-delete-of-entity-record-based-on-parent-field-val

#entity-framework 

親フィールド値に基づいてエンティティレコードの削除を制限する

Getting Started With Entity Framework Core | Code First Approach | CRUD Operations

Getting Started With Entity Framework Core | Code First Approach | CRUD Operations

Explained about what is Entity Framework Core, How to create Database & Tables with Code First Approach and how to perform basic CRUD Operations. 

#csharp #entity-framework #sqlserver 

https://youtu.be/ySlI43306pw

Getting Started With Entity Framework Core | Code First Approach | CRUD Operations

How to Create Model From Database using Entity Framework Core

In this video, I have explained that how to create the model from the database using the entity framework core. It is really super easy to generate models from an existing database. In this video, I have explained how to create the model from SQL table using C# in Entity Framework Core.

#entity-framework 

 

How to Create Model From Database using Entity Framework Core

How to Call Stored Procedure in Entity Framework Core

Hello guys, In this video I have demonstrated that how to call stored procedure in entity framework core with table-valued parameter. This is helpful for those who want to insert more than one row into the database using Entity Framework Core (ExecuteSqlInterpolated). You will also learn here to use ExecuteSqlInterpolated for calling a procedure with User-Defined Table Type as a parameter in Asp.Net Core.
#aspdotnet #entity-framework 

How to Call Stored Procedure in Entity Framework Core