Entity Framework : load database from text files - entity-framework

I need to load object to my database from .txt files. But Im frankly a little bit lost on where to begin, and running out of time.
for example I have this file, where the "#" is the separator between the column values.
1#1#5#Fotocopia Cedula
1#2#5#Pedido de Antecedentes
2#3#5#Licencia de Contruccion
2#4#5#Permiso de Ruidos
3#5#1#Recibo Multa
4#6#5#Reserva volqueta
5#7#6#pedir cedula o algo asi
5#8#2#etapa Alternativa
6#9#6#pedir cedula o algo asi
7#10#6#pedir cedula o algo asi
7#11#1#pedir cedula o algo asi
8#12#4#pedir cedula o algo asi
9#13#6#pedir cedula o algo asi
9#14#2#segunda etp
this is the corresponding class on my project
public class Etapa
{
//este tiene que ser autogenerado
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Codigo { get; set; }
[Required(ErrorMessage = "El Lapso dias Etapa no se puede dejar vacío")]
[Range(0, int.MaxValue, ErrorMessage = "El valor debe ser mayor que {0}")]
//Cambiar el nombre que se desplegará en el formulario
[DisplayName("Lapso dias Etapa")]
public int LapsoMaximoDias { get; set; }
[Required(ErrorMessage = "La Descripcion Etapa no se puede dejar vacía")]
//Cambiar el nombre que se desplegará en el formulario
[DisplayName("Descripcion Etapa")]
//Indicar largo maximo y minimo
[StringLength(50,MinimumLength =3)]
public string Descripcion { get; set; }
}
How can I extract the data, and save them as entities of this class?
I want to have a method that I can call with a button, so it can load all the data from those files every time I want it (or update them)
Tks for your time, sorry if it's a broad question.

Related

EF - Do not increase the id value when using Seeding class

I am developing a project in .net core 2.1.1 and I am using a Postgree 12 database.
In my project I have a seeding class, and the objects created in the seeding are created normally in my database, but when I try to create a record in the bank after performing the seeding, I get an ID violation error.
PostgresException: 23505: duplicate key value violates unique
constraint "PK_Linha"
this is my seeding class:
public class SeedingService
{
//Populariza o BD
private MesContext _context;
public SeedingService(MesContext context)
{
_context = context;
}
public void Seed()
{
_context.Migrar();
if ( _context.Linha.Any()) // este if serve para verificar se já existe dados no BD
{
// operação Any verifica se já existe algo na tabela x
return; // se já existe retorna Obs: "O BD já foi populado"
}
Linha l1 = new Linha(1, "Linha 1", "descricao da linha1");
Linha l2 = new Linha(2, "Linha 2", "descricao da linha2");
Linha l3 = new Linha(3, "Linha 3", "descricao da linha3");
// add os dados no BD
_context.Linha.AddRange(l1,l2,l3);
_context.SaveChanges();
}
}
this is my model:
public class Linha
{
public int Id { get; set; }
[Required(ErrorMessage = "Campo {0} é obrigatório")] // {0} é o campo Name
[StringLength(25, MinimumLength = 3,ErrorMessage = "O campo {0} deve ter entre {2} a {1} caracteres")]
public string Nome { get; set; }
[StringLength(200, MinimumLength = 5, ErrorMessage = "O campo {0} deve ter entre {2} a {1} caracteres")]
[Display(Name = "Descrição")]
public string Descricao { get; set; }
public ICollection<Estoque> Estoques { get; set; } = new List<Estoque>();
public ICollection<OrdemProducao> OrdensProducao { get; set; } = new List<OrdemProducao>();
public ICollection<LinhaEquipamento> LinhaEquipamentos { get; set; } = new List<LinhaEquipamento>();
public Linha()
{
}
public Linha(int id, string nome, string descricao)
{
Id = id;
Nome = nome;
Descricao = descricao;
}
}
This is my Controller:
public class LinhaController : Controller
{
private readonly LinhaService _context;
private readonly UsuarioService _userContext;
public LinhaController(LinhaService context,
UsuarioService userContext)
{
_context = context;
_userContext = userContext;
}
public async Task<IActionResult> Index()
{
var idUser = Int32.Parse(User.FindFirst("IdUsuario")?.Value);
if (!await _userContext.VerificaPermissao( // se ele n possui permissão
idUser, "Perm_Linha", ""))
{
return RedirectToAction("SemPermissao", "Home", new { area = "" });
}
if (!await _userContext.VerificaPermissao( // se ele n possui permissão
idUser, "Perm_Linha", "Sub_Deletar"))
{
ViewBag.PossuiDelete = false; // n possui
}
else
{
ViewBag.PossuiDelete = true; // possui
}
var list = await _context.FindAllAsync();
return View(list);
}
//GET CREATE
public async Task<IActionResult> Create()
{
var idUser = Int32.Parse(User.FindFirst("IdUsuario")?.Value);
if (!await _userContext.VerificaPermissao( // se ele n possui permissão
idUser, "Perm_Linha", "Sub_Criar"))
{
return StatusCode(403);
}
return View();
}
//POST CREATE
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(Linha obj)
{
/*verifica se post é valido. Se o js estiver desabilitado no navegador do usuario
ele consegue dar post vazio, esse if serve para previnir isso*/
if (!ModelState.IsValid)
{
return View(obj);
}
if (await _context.VerificaNome(obj.Nome, -1)) // se existe login
{
return Json("Erro: Este Nome já existe.");
}
await _context.InsertAsync(obj);
return Json("Success");
}
}
This same situation was reported here, but I was not successful in finding a solution for this.
would anyone know why I'm getting this error?
Linha's Id is automatically discovered by EF Core and set up as an auto-incrementing key - that means that database is responsible for assigning ID values. However, in your seeding you are assigning the IDs yourself via a constructor (1, 2, 3). PostgreSQL does not update the auto-increment value, so the next Linha you try to insert will get an auto-generated key of 1, which conflicts with the seeded value.
To make this work, remove the id constructor of Linha and leave it uninitialized. This will make PostgreSQL generate auto-increment values for your seeded values as well, and all should work.

Check for specific element in a list in Drools using dsl,dslr

I just started using drools workbench 6.5.0
I have two classes
class Client{
String name;
String age;
List<Products> products;
}
class Product {
String code;
String description;
}
There is a way can i fire rules that matches an element in the list of products of determined client using dsl and dslr?
i used the following dsl
[keyword][]regla=rule
[keyword][]cuando=when
[keyword][]entonces=then
[keyword][]fin=end
[when][]es menor o igual que=<=
[when][]es menor que=<
[when][]es mayor o igual que=>=
[when][]es mayor que=>
[when][]es igual que===
[when][]igual===
[when][]- {campo:\w*} {operador} {valor:\d*}={campo} {operador} {valor}
[when][]Hay un cliente =$c : Client($products: products)
[when][]nombre = name
[when][]edad = age
[when][]codigo = code
[when][]Hay producto = $p : Product() from $products
and the following condition
cuando
Hay un cliente
- edad es mayor o igual que 12
- nombre igual "John"
Hay producto
- codigo es igual que "4"
Your code works for me. The test below prints correct client name which has respective product code.
test
#DroolsSession(resources = { "classpath:/test.rdslr", "classpath:/business.dsl" })
public class PlaygroundTest {
#Rule
public DroolsAssert drools = new DroolsAssert();
#Test
public void testIt() {
drools.insertAndFire(new Client("client1", 40, asList(new Product("1", "product 1"), new Product("2", "product 2"))));
drools.insertAndFire(new Client("John", 50, asList(new Product("3", "product 3"), new Product("4", "product 4"))));
}
}
rule
regla X
cuando
Hay un cliente
- edad es mayor o igual que 12
- nombre igual "John"
Hay producto
- codigo es igual que "4"
entonces
print client name
fin
dsl
[keyword][]regla=rule
[keyword][]cuando=when
[keyword][]entonces=then
[keyword][]fin=end
[when][]es menor o igual que=<=
[when][]es menor que=<
[when][]es mayor o igual que=>=
[when][]es mayor que=>
[when][]es igual que===
[when][]igual===
[when][]- {campo:\w*} {operador} {valor:\d*}={campo} {operador} {valor}
[when][]Hay un cliente =$c : Client($products: products)
[when][]nombre = name
[when][]edad = age
[when][]codigo = code
[when][]Hay producto = $p : Product() from $products
[then]print client name = System.out.println($c.name);
model
public class Client {
public String name;
public int age;
public List<Product> products;
public Client(String name, int age, List<Product> products) {
this.name = name;
this.age = age;
this.products = products;
}
public List<Product> getProducts() {
return products;
}
}
public class Product {
public String code;
public String description;
public Product(String code, String description) {
this.code = code;
this.description = description;
}
}
test output
00:00:00 --> inserted: Client[name=client1,age=40,products=[org.droolsassert.Product#4fbdc0f0, org.droolsassert.Product#2ad3a1bb]]
00:00:00 --> fireAllRules
00:00:00 --> inserted: Client[name=John,age=50,products=[org.droolsassert.Product#71e9a896, org.droolsassert.Product#6b9267b]]
00:00:00 --> fireAllRules
00:00:00 <-- 'X' has been activated by the tuple [Client, Product]
John
After inserting first client no rules got triggered, after inserting John rule was triggered and client name printed.
What unexpected result did you get?

Invalid date with BreezeJS and Hottowel

i've a problem whit breeze returned DateTime... i've tried also to update BreezeJs to the latest version but nothing change. I use breezeJs with HotTowel SPA
Controller:
[BreezeController]
public class ContribuentiController : ApiController
{
readonly EFContextProvider<LarksTribContext> _contextProvider =
new EFContextProvider<LarksTribContext>();
[System.Web.Http.HttpGet]
public string Metadata()
{
return _contextProvider.Metadata();
}
// ~/api/todos/Todos
// ~/api/todos/Todos?$filter=IsArchived eq false&$orderby=CreatedAt
[System.Web.Http.HttpGet]
public IQueryable<Contribuente> Contribuenti()
{
if (_contextProvider.Context.Contribuente != null)
{
return _contextProvider.Context.Contribuente.Include("Residenze.Strada");//.Include("Residenze").Include("Residenze.Strada");
}
else
{
return null;
}
}
[System.Web.Http.HttpPost]
public SaveResult SaveChanges(JObject saveBundle)
{
return _contextProvider.SaveChanges(saveBundle);
}
}
Model:
[Table(name: "Contribuenti")]
public class Contribuente
{
[Key]
public int Id { get; set; }
[MaxLength(30,ErrorMessage = "Il cognome non deve superare i 30 caratteri")]
public string Cognome { get; set; }
[MaxLength(35, ErrorMessage = "Il nome non deve superare i 35 caratteri")]
public string Nome { get; set; }
[MaxLength(16, ErrorMessage = "Il Codice fiscale non deve superare i 16 caratteri")]
public string CodiceFiscale { get; set; }
public virtual ICollection<Residenza> Residenze { get; set; }
}
[Table(name: "Residenze")]
public class Residenza
{
[Key, Column(Order = 0)]
public int Id { get; set; }
public int ContribuenteId { get; set; }
[ForeignKey("ContribuenteId")]
public Contribuente Contribuente { get; set; }
public DateTime? DataInizio { get; set; }
public int StradaId { get; set; }
[ForeignKey("StradaId")]
public Strada Strada { get; set; }
public int Civico { get; set; }
public string Interno { get; set; }
public string Lettera { get; set; }
}
[Table(name: "Strade")]
public class Strada
{
[Key]
public int Id { get; set; }
[MaxLength(20,ErrorMessage = "Il toponimo deve contenere al massimo 20 caratteri")]
public string Toponimo { get; set; }
[MaxLength(50, ErrorMessage = "Il nome deve contenere al massimo 50 caratteri")]
public string Nome { get; set; }
}
when i make this query:
var query = breeze.EntityQuery.
from("Contribuenti").expand(["Residenze"], ["Strada"]);
the json response is:
[{"$id":"1","$type":"LarksTribUnico.Models.Contribuente, LarksTribUnico","Id":1,"Cognome":"Manuele","Nome":"Pagliarani","CodiceFiscale":"HSDJSHDKHSD","Residenze":[{"$id":"2","$type":"LarksTribUnico.Models.Residenza, LarksTribUnico","Id":5,"ContribuenteId":1,"Contribuente":{"$ref":"1"},"DataInizio":"2012-12-10T22.00.00.000","StradaId":4,"Strada":{"$id":"3","$type":"LarksTribUnico.Models.Strada, LarksTribUnico","Id":4,"Toponimo":"Via","Nome":"Milano"},"Civico":0}]}]
But in result of query "DataInizio" is always marked as "Invalid date".
Any idea aout the problem?
Thanks
Breeze server side converts SQL Server DateTime to ISO 8601. In my code (breeze v0.72) dates seem to end up in UTC in SQL, and get converted back to local somewhere in breeze.
Check the Breeze docs on dates. http://www.breezejs.com/documentation/date-time
or, as suggested in the breeze docs, you can add moment.js to your project if HotTowel does not. https://github.com/moment/moment
Moment recognizes the JSON you are describing.
A moment() is different than a JavaScript date, but it is easier to manipulate and parse.
This code you the current browser date from moment.
var now = window.moment().toDate();
This code demonstrates how to turn an ISO into a JavaScript Date object through moment.
// ISO 8601 datetime returned in JSON.
// In your code, you would pull it out of your the
// return variable in your dataservice.js
var DataInizio = "2012-12-10T22.00.00.000"
// convert your variable to a moment so you can parse it
var momentdatainizio = window.moment(DataInizio);
// convert the ISO to a javascript Date object so you can use it in js.
var mydate = window.moment(DataInizio).toDate();
Your Stada will end up in the breeze Metadata store which you use to populate your viewModel.
Retrieve the strada from the Metadata store or the database with something like this code in your dataservice.js. I am being a little more verbose than necessary so you can debug.
var getStrada = function (stradaId, callback) {
var query = EntityQuery.from("Strada")
.using(manager);
var pred = new breeze.Predicate("idd", "eq", stradaId);
// create the query
var queryb = query.where(pred);
// check the MetadataStore to see if you already have it
var localsession = queryb.executeLocally();
if (localsession) {
if (localsession.length > {
window.app.vm.strada.strada(data.results);
return localsession;
}
}
// get it from the server
else {
// return the promise to prevent blocking
// then set your viewModel when the query fulfills
// then make your callback if there is one
// handle the fail in your queryFailed function if there is a problem
return manager.executeQuery(queryb)
.then(function (data) {
window.app.vm.strada.strada(data.results);
})
.then(function () {
if ((typeof callback !== 'undefined' && callback !== null)) {
callback();
}
})
.fail(function () {
queryFailed();
});
}
};
Here is a fragment of a ko viewModel in strada.js
app.vm.strada = (function ($, ko, dataservice, router) {
var strada = ko.observable();
...
return {
strada : strada,
...
})($, ko, app.dataservice, app.router);
Here is the custom binding handler for knockout in the ko.bindingHandlers.js. This code is slightly verbose so you can debug the intermediate variables.
window.ko.bindingHandlers.DataInizio = {
// viewModel is a Strada
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var value = valueAccessor(), allBindings = allBindingsAccessor();
var valueUnwrapped = window.ko.utils.unwrapObservable(value);
var $el = $(element);
if (valueUnwrapped.toString().indexOf('Jan 1') >= 0)
$el.text("Strada not Started");
else {
var date = new Date(valueUnwrapped);
var d = moment(date);
$el.text(d.format('MM/DD/YYYY'));
}
}
};
Here is the html for the binding handler
...
Strada DataInizio:
...
I wrote this code based upon my code using Breeze v0.72 which uses sammy.js as the router. Your mileage may vary with newer versions of breeze and Durandel.

Multiple aggregates in linq to entities (code first)

Given the following model, I want to be able to retrieve the number of points gained for a single player and the average number of point gained for all players given a time period. This should be done in a single db query (I also want other stats e.g. avg points per team which will come later but the concept should be the same).
Having a bad day and getting nowhere. Can someone help me out?
public class Player
{
public int Id { get; set; }
public ICollection<PlayerGame> PlayerGames { get; set; }
...
}
public class PlayerGame
{
public int Id { get; set; }
public int Points { get; set; }
public int PlayerId { get; set; }
public Player Player { get; set; }
public int GameId { get; set; }
public Game Game { get; set; }
...
}
public class Game
{
public int Id { get; set; }
...
}
Edit:
OK. Have taken the game entity out of the equation for now and changed your code to fit in with my repo. This is what I have now:
var query = from p in _playerRepository.Query()
from pg in p.PlayerGames
group new { p, pg } by 1 into ppg
select new
{
SinglePlayerPointsGained = (from x in ppg
where x.p.Id == playerId && x.pg.Date > startDateTime
select x.pg.Points).Sum(),
AveragePoints = (from x in ppg
where x.pg.Date > startDateTime
select x.pg.Points).Average(),
};
So Now I just need the AveragePoints calculation to take players that have not played in the period into account as mentioned in the comment.
I assumed the Game class had a DateTime property. The basic idea is using the group by 1 trick
DateTime startDateTime, endDateTime;
int playerId;
var query = from p in context.Players
join pg in context.Players on p.Id equals pg.PlayerId
join g in context.Games on pg.GameId equals g.Id
group new { p, pg, g } by 1 into ppgg
select new {
SinglePlayerPointsGained = (from x in ppgg
where x.p.PlayerId == playerId
where x.g.DateTime >= startDateTime && x.g.DateTime <= endDateTime
select x.pg.Points ).Sum(),
AveragePoints = (from x in ppgg
group x.pg.Points by x.p.PlayerId into g
select g.Key).Average()
};

Generating Data Annotations from Generated Classes

I have a linq to sql object or if neccessary Entity Framework object.
I want to do MVC 2 Data Annotations for them, but I am endlessly lazy.
Is there a way to automatically generate the data annotations a-la
[Bind(Include = "Title,Description,EventDate,Address,Country,ContactPhone,Latitude,Longitude")]
[MetadataType(typeof(Dinner_Validation))]
public partial class Dinner
{
public bool IsHostedBy(string userName)
{
return HostedBy.Equals(userName, StringComparison.InvariantCultureIgnoreCase);
}
public bool IsUserRegistered(string userName)
{
return RSVPs.Any(r => r.AttendeeName.Equals(userName, StringComparison.InvariantCultureIgnoreCase));
}
}
public class Dinner_Validation
{
[Required(ErrorMessage = "Title is required")]
[StringLength(50, ErrorMessage = "Title may not be longer than 50 characters")]
public string Title { get; set; }
[Required(ErrorMessage = "Description is required")]
[StringLength(265, ErrorMessage = "Description may not be longer than 256 characters")]
public string Description { get; set; }
[Required(ErrorMessage = "HostedBy is required")]
public string HostedBy { get; set; }
[Required(ErrorMessage = "Address is required")]
public string Address { get; set; }
[Required(ErrorMessage = "Country is required")]
public string Country { get; set; }
[Required(ErrorMessage = "Phone# is required")]
public string ContactPhone { get; set; }
}
So that I don't have to do it all myself?
I think it would be redundant to generate data annotations.
Instead, I'd suggest writing an associated metadata provider which will simply cause the MVC model binding and validation to see the correct metadata for your types without requiring data annotations at all (or will supplement any data annotations you may already have).
There's an example here.
I borrowed a little from my Silverlight toolbox for this, but it seems to work just fine for MVC3 in VS2010.
Compile your project. This is important if you just created your Entity Framework model.
Right-click on your project. Click Add/New Item.
Select 'Domain Service Class' as the type. Click Add.
Select your model in the drop down.
In the list of entities, select all objects the you want data annotations for.
Check the box labeled 'Generate associated classes for metadata'. Click OK.
You will get two classes generated. Just delete the one without the .metadata. tag.
That should do it. You should now have a metadata class ready to add your annotations. (It's possible that the Domain Service Class used above was installed with the WCF RIA Services toolkit in VS2010. Not positive about that, but if you don't have this in your list of available items, that's probably the issue.)