Я создаю приложение для инвентаризации электронных компонентов. Для каждого компонента существует пакет, который будет меняться в зависимости от технологии сборки SMD или DIP. У каждого SMD и DIP есть свои параметры, поэтому я создал отдельные классы и родительский интерфейс (для использования в модели основного резистора). Мне нужно отношение «один ко многим», чтобы резистор можно было найти в пакете.
Модели:
public class Resistors
{
public string Value { get; set; }
public int Tolerance { get; set; }
public IResistorPackage Package { get; set; }
public ResistorAT AssembleTech{ get; set; }
}
У интерфейса есть два дочерних элемента:
public class ResistorPackageDIP : IResistorPackage
{
public int Id { get; set ; }
public string RP250mW { get; set; }
public string RP500mW { get; set; }
public string RP1W { get; set; }
public string RP2W { get; set; }
}
public class ResistorPackageSMD : IResistorPackage
{
public int Id { get; set; }
public string RP1206 { get; set; }
public string RP0805 { get; set; }
public string RP0603 { get; set; }
public string RP0402 { get; set; }
}
По роли «Является» оба пакета являются пакетами, которые я хочу сохранить на основе свойства IResistorAT
. Когда кто-то добавляет резистор в базу данных и выбирает SMD, он должен (из поля со списком) выбрать пакет, относящийся к SMD AKA 0603. Если он выберет DIP, ему будут предложены пакеты, связанные с DIP.
Если я соберу их вместе, они могут выбрать неправильную упаковку и технологию сборки (например, резисторы не имеют DIP 0805). Поэтому я поместил интерфейс в модель данных, поскольку его идентификатор является целым числом, однако я получаю это сообщение от Entity Framework Core:
System.InvalidOperationException: «Свойство Resistors.Package имеет тип интерфейса («IResistorPackage»). Если это навигация, вручную настройте связь для этого свойства, приведя его к сопоставленному типу сущности. В противном случае игнорируйте свойство, используя атрибут [NotMapped] или «Игнорировать» в «OnModelCreating».
Это исключение происходит в функции EnsureCreate
в базе данных. Есть ли способ лучше? Одно из моих свойств (корпуса) должно быть изменено исходя из другого свойства (технологии сборки), а двух видов резисторов я предпочитаю не иметь, так как они имеют много общего.
Значение @GerrySchmitz примерно 20 или 120 Ом.
Создайте простую базу данных SQLite, как показано ниже.
// Create a table named Resistors to store resistor data (Sql lite).
CREATE TABLE Resistors (
Id INTEGER PRIMARY KEY AUTOINCREMENT,
Value TEXT NOT NULL,
Tolerance REAL NOT NULL,
Type INTEGER NOT NULL,
PowerRating REAL NOT NULL,
PackageType TEXT NOT NUL,
-- Add more columns as needed
);
// Ensure you have the necessary packages installed in your project (VS 2022):
dotnet add package Microsoft.EntityFrameworkCore.Sqlite
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Microsoft.EntityFrameworkCore.Tools
public enum ResistorType
{
NONE, // 0
SMD, // 1
DIP // 2
// etc
}
// Create a Resistor class that represents your resistor entity:
public class Resistor
{
public int Id { get; set; } // Primary key
public string Value { get; set; } // Value of the resistor (e.g., "10K")
public double Tolerance { get; set; } // Tolerance percentage (e.g., 5 for ±5%)
public int Type { get; set; } // Type of resistor (NONE=0, SMD=1, DIP=2, etc.)
public double PowerRating { get; set; } // PowerRating of the resistor (e.g., 250mW, 1W, 2W, etc)
public string PackageType { get; set; } // e.g., "0402", "0603", "0805", "DIP-8", "DIP-16"
}
// Set up your ResistorDbContext to define the database context and specify the Resistors table:
public class ResistorDbContext : DbContext
{
public DbSet<Resistor> Resistors { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite("Data Source=resistors.db"); // SQLite connection string
}
}
// Generate migrations and apply them to create the database schema:
dotnet ef migrations add InitialCreate
dotnet ef database update
// Create a service or repository class (ResistorService in this example) to encapsulate CRUD operations:
public class ResistorService
{
private readonly ResistorDbContext _context;
public ResistorService(ResistorDbContext context)
{
_context = context;
}
// Create operation
public void AddResistor(Resistor resistor)
{
_context.Resistors.Add(resistor);
_context.SaveChanges();
}
// Read operations
public List<Resistor> GetAllResistors()
{
return _context.Resistors.ToList();
}
public Resistor GetResistorById(int id)
{
return _context.Resistors.Find(id);
}
// Update operation
public void UpdateResistor(Resistor resistor)
{
_context.Resistors.Update(resistor);
_context.SaveChanges();
}
// Delete operation
public void DeleteResistor(int id)
{
var resistor = _context.Resistors.Find(id);
if (resistor != null)
{
_context.Resistors.Remove(resistor);
_context.SaveChanges();
}
}
}
// Here’s how you might use the ResistorService in your application:
class Program
{
static void Main(string[] args)
{
using (var context = new ResistorDbContext())
{
var service = new ResistorService(context);
// Create SMD resistor
var smdResistor = new Resistor
{
Value = "10K",
Tolerance = 1,
Type = (int)ResistorType.SMD
PowerRating = 0.25
PackageType = "0402"
};
service.AddResistor(smdResistor);
// Create DIP resistor
var dipResistor = new Resistor
{
Value = "10K",
Tolerance = 5,
Type = (int)ResistorType.DIP
PowerRating = 1
PackageType = "DIP-8"
};
service.AddResistor(dipResistor);
// Read all
var allResistors = service.GetAllResistors();
foreach (var resistor in allResistors)
{
Console.WriteLine($"ID: {resistor.Id}, Value: {resistor.Value}, Tolerance: {resistor.Tolerance}, Type: {resistor.Type}, PowerRating: {resistor.PowerRating}, PackageType: {resistor.PackageType}");
}
// Update
var resistorToUpdate = service.GetResistorById(1);
if (resistorToUpdate != null)
{
resistorToUpdate.Tolerance = 1; // Change tolerance to 1%
service.UpdateResistor(resistorToUpdate);
}
// Delete
service.DeleteResistor(2); // Assuming resistor with ID 2 exists and is to be deleted
}
}
}
Это не решает мою проблему, вы все равно можете предоставить DIP-пакет со значениями SMD.
@S2G Почему вы храните номинальную мощность в разных столбцах? Если вы хотите ввести резисторы в зависимости от их типа (SMD или DIP), вы можете использовать фильтр в пользовательском интерфейсе. Если вы хотите отображать резисторы в зависимости от их типа (SMD или DIP) из базы данных, вы можете использовать фильтры на уровне данных.
@S2G Что произойдет, если вы захотите отобразить резистор типа SMD, будет много пустых столбцов. Я предлагаю улучшить вашу таблицу, как указано выше. Это облегчит вам поиск резисторов по нужным критериям.
Вот рекомендуемая отправная точка для проектирования базы данных; на основе моего ограниченного знания ваших требований. (Класс резистора в таблице является «единственным» по сравнению с «Резисторами»).
public class Resistor {
public string Value { get; set; }
public int Tolerance { get; set; }
public List<int> PackageIds { get; set; }
// ??
//public ResistorAT AssembleTech { get; set; }
}
public enum Technology : byte {
Undefined = 0,
//
SMD,
DIP
} // end enum.
public class ResistorPackage {
public static Dictionary<int, ResistorPackage> Available =
new Dictionary<int, ResistorPackage>();
public int Id { get; set; }
public Technology Technology { get; set; }
public List<string> Resistors { get; set; } = new List<string>();
/// <summary>
///
/// </summary>
internal static ResistorPackage FirstOrDefault( string value ) {
foreach ( var package in Available ) {
if ( package.Value.Resistors.Contains( value ) ) {
return package.Value;
}
} // end for.
return null;
}
} // end class.
Это больше о «дизайне», чем о «интерфейсах». Ваши «пакеты», похоже, имеют «повторяющиеся группы»; которые с точки зрения «нормализации» должны быть «коллекциями» (какими-то). Не хватает только «технического» типа: SMD или DIP. А «Значение» могло бы использовать более описательное имя. Это «ключ», «имя», «номинал резистора»?