.ToDataTable() method misses column - c#

In the code below, I am converting the results of an SQL View to a DataTable:
DataTable tierOnes = db.xxxxxxxxx_vw_TierOnes.ToDataTable();
The View is defined in a separate class:
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DPN.Entities.Moonboot
{
[Table("vw_TierOnes", Schema = "xxxxxxxxx")]
public class xxxxxxxxx_vw_TierOnes
{
[Key]
public Guid TierOneID { get; set; }
public string TierOneName { get; set; }
public DateTime DateCreated { get; set; }
public Boolean IsActive { get; set; }
public int? CreatedByUserID { get; set; }
}
}
I try to retrieve data from columns AS BELOW:
foreach (DataRow row in tierOnes.Rows)
{
if (row["IsActive"].ToString() == "True")
{
TierOne t1 = new TierOne();
t1.Id = Guid.Parse(row["TierOneID"].ToString());
t1.Name = row["TierOneName"].ToString();
output.TierOnes.Add(t1);
}
}
I get the following error:
Column 'TierOneID' does not belong to table .
Where did my column go?
More importantly, how do I get this data?

Related

How do I iteratively assign to a nested list within an object in C#?

I've been asked to replicate a complex xml structure we use within our internal systems, against data retrieved from another system. Unfortunately the xml structure is improvised and we have no specification for it.
I've been mapping out it's structure in C# classes so that I can assign those properties with values from the database and ultimately serialise it as xml.
I've hit a bit of a road block in terms of iteratively adding new list items to a nested list within an object that's already being intialised as a list and being looped through. To make matters more complicated I need to use a value from the iteration to filter down the dataset being used to instantiate the second loop round.
Sorry for the poor explanation - open to rewording... hopefully however the example I've written will demonstrate what I'm trying to do:
using System;
using System.Collections.Generic;
using System.Data;
public class TransactionModel
{
public int Id { get; set; }
public string Description { get; set; }
public DateTime SysDate { get; set; }
public List<TransactionItemModel> Trade { get; set; } = new List<TransactionItemModel>();
}
public class TransactionItemModel
{
public int ItemId { get; set; }
public int TransactionId { get; set; }
public string ItemDescription { get; set; }
public decimal ItemNetAmount { get; set; }
}
public class Program
{
public void Main()
{
DataTable tranResultSet = MethodToReturnResultsFromTranQuery();
DataTable itemResultSet = MethodToReturnResultsFromItemQuery();
var transactions = new List<TransactionModel>();
foreach (DataRow tran in tranResultSet.Rows)
{
transactions.Add(
new TransactionModel() {
Id = (dynamic)tran["Id"],
Description = (dynamic)tran["Description"],
SysDate = (dynamic)tran["SysDate"],
//Trade = <Stuck Here>
// Need to iterate through itemResultSet, adding to TransactionModel.Trade
// where item["TransactionId"] = tran["Id"]
}
);
}
}
}
This approach doesn't set the Trade collection initially, but populates it once you go through the Items. There's likely a lot of optimization that can be added, but this might get you started.
public class TransactionModel
{
public int Id { get; set; }
public string Description { get; set; }
public DateTime? SysDate { get; set; }
public List<TransactionItemModel> Trade { get; set; }
public TransactionModel(DataRow row)
{
if(row == null)
throw new ArgumentNullException(nameof(row));
Id = row.Field<int>("Id");
Description = row.Field<string>("Description");
SysDate = row.Field<DateTime?>("SysDate");
Trade = new List<TransactionItemModel>();
}
}
public class TransactionItemModel
{
public int ItemId { get; set; }
public int TransactionId { get; set; }
public string ItemDescription { get; set; }
public decimal? ItemNetAmount { get; set; }
public TransactionItemModel(DataRow row)
{
if(row == null)
throw new ArgumentNullException(nameof(row));
ItemId = row.Field<int>("Id");
TransactionId = row.Field<int>("TransactionId");
ItemDescription = row.Field<string>("ItemDescription");
ItemNetAmount = row.Field<decimal?>("ItemNetAmount");
}
}
public static class Program
{
private static void Main()
{
DataTable tranResultSet = MethodToReturnResultsFromTranQuery();
DataTable itemResultSet = MethodToReturnResultsFromItemQuery();
var transactions = tranResultSet.AsEnumerable()
.Select(r => new TransactionModel(r));
foreach(TransactionModel transaction in transactions)
{
var items = itemResultSet.AsEnumerable()
.Where(r => r.Field<int>("TransactionId") == transaction.Id)
.Select(r => new TransactionItemModel(r));
transaction.Trade.AddRange(items);
}
}
}
It's likely going to be ideal to query your ItemResultSet based on the current TransactionId instead of grabbing them all up front. You could implement a DataReader, or use Dapper.

How to use FIND() for a MongoDB query on a MVC .net C# project

I'm connecting a MongoDB (Azure) with a MVC .NET C# project. The connection and object definition are working very good so far. My problem is when I try to add the method FIND() to return all the data in the object USER.
My Model:
using System;
using System.Collections.Generic;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
namespace backendnet.Models
{
public class MongoCore
{
public class DB
{
static MongoClient Client = new MongoClient("mongodb://mydbconnect");
static public IMongoDatabase Database = Client.GetDatabase("mydb");
static public IMongoCollection<User> Users = Database.GetCollection<User>("users");
}
public class User
{
[BsonId]
public ObjectId Id { get; set; }
[BsonElement("email")]
public string Email { get; set; }
[BsonElement("password")]
public string Password { get; set; }
[BsonElement("name")]
public List<DimensionName> Name { get; set; }
[BsonElement("address")]
public List<DimensionAddress> Address { get; set; }
[BsonElement("permissions")]
public List<DimensionPermissions> Permissions { get; set; }
[BsonElement("status")]
public string Status { get; set; }
[BsonElement("created")]
public string Created { get; set; }
[BsonElement("updated")]
public string Updated { get; set; }
}
public class DimensionName
{
[BsonElement("first")]
public string First { get; set; }
[BsonElement("last")]
public string Last { get; set; }
}
public class DimensionAddress
{
[BsonElement("stree")]
public string Stree { get; set; }
[BsonElement("number")]
public string Number { get; set; }
[BsonElement("city")]
public string City { get; set; }
[BsonElement("state")]
public string State { get; set; }
[BsonElement("zipcode")]
public string Zipcode { get; set; }
[BsonElement("type")]
public string Type { get; set; }
}
public class DimensionPermissions
{
[BsonElement("list")]
public string List { get; set; }
[BsonElement("create")]
public string Create { get; set; }
[BsonElement("edit")]
public string Edit { get; set; }
[BsonElement("delete")]
public string Delete { get; set; }
}
}
}
My Controller:
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using backendnet.Models;
using MongoDB.Bson;
namespace backendnet.Controllers
{
public class DashboardController : Controller
{
private string _viewFolder = "../Admin/Dashboard";
public ActionResult Index()
{
var results = new MongoCore.DB();
ViewData["ListPost"] = results.ToJson();
return View (_viewFolder);
}
}
}
My View partial:
<p>HERE: #ViewData["ListPost"]</p>
I get this:
HERE: { }
So I tried adding in the Model -> DB the method Find:
MongoCursor<User> cursor = Users.Find("Email" != "");
But always show an error:
Expression is always 'true' ["Email" != ""]
May anyone show me what I'm missing here?
I Don't See you calling MongoDB.Find()? I have pasted below my code I use for MongoDB C# driver in order to attain a record based on a key:value pair in my MongoDB database.
The Find or FindAsync method both require a BsonDocument Argument, which can be created using the Builders as seen below. Your filter can be empty, which would get all records since you are not filtering out anything.
Once you call the find method, you will be able to access the information using Lambda, or other query methods. You can see in my query i just need one record so i ask for FirstOrDefault. Hope this helps.
async Task<Document> IDal.GetRecordAsync(string key, string value)
{
try
{
if (Database == null) ((IDal)this).StartConnection();
var filter = Builders<BsonDocument>.Filter.Eq(key, value);
var cursor = await Collection.FindAsync(filter);
var bsondocument = cursor.FirstOrDefault();
return bsondocument == null ? null : _converter.ConvertBsonDocumentToDocument(bsondocument);
}
catch (Exception ex)
{
Console.WriteLine(ex);
return null;
}
}
public ActionResult GetUsers()
{
MongoServer objServer = MongoServer.Create("Server=localhost:27017");
MongoDatabase objDatabse = objServer.GetDatabase("DBName");
List UserDetails = objDatabse.GetCollection("Colletion_Name").FindAll().ToList();
return View(UserDetails);
}

ASP.Net MVC forms/model binding and delete records?

I have a model that I'm loading into a table within a form. The records are retrieved from an Oracle DB using EF6 and loaded into the model.
I also want the user to be able to select records to delete from the database via a checkbox in each row in the form.
The function to retrieve the Attendees:
public List<WebinarAttendeesList> getAttendees(string webinarKey)
{
string connectionString = "Password=password;User Id=user;Data Source=Oracle";
List<WebinarAttendeesList> r = null;
using (webinarAttendeesListDbContext context = new webinarAttendeesListDbContext(connectionString))
{
var result = from w in context.WebinarAttendeesList
where w.webinarKey == webinarKey
orderby w.FirstPollCount, w.SecondPollCount
select w;
r = result.ToList();
}
return r;
}
Here is the model:
[Table("WEBINARATTENDEESLIST")]
public class WebinarAttendeesList {
[Key, Column("WAL_ID")]
public int wa_id { get; set; }
[Column("WAL_CLI_RID")]
public int ParticipantID { get; set; }
[Column("WAL_FULLNAME")]
public string FullName { get; set; }
[Column("WAL_EMAIL")]
public string Email { get; set; }
[Column("WAL_JOINTIME")]
public string JoinTime { get; set; }
[Column("WAL_TIMEINSESSION")]
public string TimeInSession { get; set; }
[Column("WAL_LEAVETIME")]
public string LeaveTime { get; set; }
[Column("WAL_FIRSTPOLLCOUNT")]
public int FirstPollCount { get; set; }
[Column("WAL_SECONDPOLLCOUNT")]
public int SecondPollCount { get; set; }
[Column("WAL_ATTENDEDWEBINAR")]
public int AttendedWebinar { get; set; }
[Column("WAL_MAKEUP")]
public int Makeup { get; set; }
[Column("WAL_COMMENTS")]
public string Comments { get; set; }
[Column("WAL_REGISTRANTKEY")]
public string RegistrantKey { get; set; }
[Column("WAL_WEBINARKEY")]
public string webinarKey { get; set; }
}
When the form is submitted, I am passing the model to a function to store the records in EF6.
public ActionResult PostAttendees(ICollection<WebinarAttendeesList> attendees)
{
foreach (WebinarAttendeesList attendee in attendees)
{
UpdateAttendee(attendee);
}
}
How would I edit the model to allow this delete the records that are selected and update the ones that don't have the checkbox selected?
If I put an int delete property on the model that has no Column attribute I get this exception:
ORA-00904: "Extent1"."delete": invalid identifier
I found this tutorial but I'm NOT using any helpers in the creation of the form and do not have any ViewModels and it also doesn't explain how to handle doing different things to the different records based on the checkbox: http://johnatten.com/2014/01/05/asp-net-mvc-display-an-html-table-with-checkboxes-to-select-row-items/
Is there a better way to do this?
Yes. All models properties in EF are suppose to be column. You should use NotMapped attribute if you don't want property to be treated as a 'column' in database.

Getting NULL for a row a type nvarchar when I try to use LINQ to mirror my database

I have a table created with
CREATE TABLE orgs ( O_Id int NOT NULL identity(1,1), orgname nvarchar (MAX) NOT NULL, PRIMARY KEY (O_Id) );
and a few rows of it then initialized with
INSERT INTO orgs (orgname) VALUES ('someOrg');
INSERT INTO orgs (orgname) VALUES ('otherOrg');
I've looked in Visual Studio's Server Object Explorer to make sure the table and its columns and the 2 rows were successfully created.
My model that mirrors this table is
[Table(Name = "orgs")]
public class Organization
{
public Organization()
{
}
[Column]
public int O_Id { get; set; }
public string orgname { get; set; }
}
In my controller I have, a test,
PortalData PD = new PortalData();
foreach (Organization x in PD.orgs)
{
ViewBag.orgsInfo += ("O_id=" + (x.O_Id).ToString() + ", org=" + x.orgname + "\n");
}
The problem is that (x.O_Id).ToString() is spitting out the correct value but x.orgname is undefined.
My hypothesis is that this has something to do with an intermediate conversion that needs to take place for the data type of the column to be used as a C# string.
EDIT: Added code for PortalData below
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Linq;
using System.Data.Linq.Mapping;
namespace AllyPortal.Models
{
[Database]
public class PortalData : DataContext
{
public PortalData()
: base("...")
{
}
public Table<AssetLink> links;
public Table<AssetFile> files;
public Table<Organization> orgs;
public Table<Category> cats;
}
[Table( Name = "links")]
public class AssetLink
{
public AssetLink()
{
}
[Column]
public int rownum { get; set; }
[Column]
public int linkid { get; set; }
[Column]
public int fileid { get; set; }
}
[Table( Name = "files" )]
public class AssetFile
{
public AssetFile()
{
}
[Column]
public int fileid { get; set; }
public string org { get; set; }
public string category { get; set; }
public string loc { get; set; }
}
[Table(Name = "orgs")]
public class Organization
{
public Organization()
{
}
[Column]
public int O_Id { get; set; }
public string orgname { get; set; }
}
[Table(Name = "cats")]
public class Category
{
public Category()
{
}
[Column]
public int O_Id { get; set; }
public string cat { get; set; }
}
}
From the MSDN documentation:
Use this attribute to designate a member of an entity class to represent a column in a database table. ... Only those entity class members identified as columns are persisted when LINQ to SQL saves changes to the database.
That would suggest that you need to add the [Column] attribute to all of the properties in your AssetFile, Organization and Category classes. Without the attribute, the value of those properties will not be loaded from, or persisted to, the database.

how to return two variables from controller to view in mvc3

Hi Im a new to MVC3 and i am having problem in returning two variables here is my controller code
public ActionResult Create()
{
using (var context = new material_managementEntities())
{
var blogs = (from cs in context.GROUP_MASTER
where cs.GROUP_NAME == "MIC"
select cs.ID).FirstOrDefault();
var droplist = new TRANSACTION();
droplist.GROUP_MASTER_ID = blogs;
droplist.GROUP_NAME = "MIC";
var directory_master = db.DIRECTORY_MASTER.Include(d => d.CATEGORY_MASTER).Include(d => d.REPRESENTATIVE_MASTER);
droplist.dir_data = directory_master.ToList();
return View(droplist);
}
}
here Transaction is one table and DIRECTORY_MASTER is another and GROUP_MASTER_ID is a foreign key to Transaction table, what i want is the toList data will be displayed in a modalpopup box so i need to pass data available from both tables
here is model
namespace Material.Models
{
using System;
using System.Collections.Generic;
using System.Web.Mvc;
public partial class TRANSACTION
{
public int ID { get; set; }
public int GROUP_MASTER_ID { get; set; }
public string GROUP_NAME { get; set; }
public string dir_data { get; set; }
public string NAME { get; set; }
public string ADDRESS_DETAILS { get; set; }
public string CONTACT_PERSON { get; set; }
public Nullable<int> TEL_NO { get; set; }
public Nullable<int> CELL { get; set; }
public Nullable<int> FAX { get; set; }
public string EMAIL_ID { get; set; }
public Nullable<int> OPENING_BALANCE { get; set; }
public Nullable<System.DateTime> OPENING_BALANCE_DATE { get; set; }
public string VERIFIED { get; set; }
public virtual GROUP_MASTER GROUP_MASTER { get; set; }
}
}
Either you can use a
viewbag.directory_master = (db.DIRECTORY_MASTER.Include(d => d.CATEGORY_MASTER).Include(d => d.REPRESENTATIVE_MASTER)).ToList();
and then iterate your viewbag.directory_master from your model and display the required ones.
or you can create a custom view model containing directory_master and TRANSACTION like
public class DashboardModel
{
public TRANSACTION transation{get;set;}
public List<directory_master>directoryMaster{get;set;}
}
so your action will be like this
public ActionResult Create()
{
using (var context = new material_managementEntities())
{
var blogId = (from cs in context.GROUP_MASTER
where cs.GROUP_NAME == "MIC"
select cs.ID).FirstOrDefault();
DashboardModel dashboardModel= new DashboardModel();
dashboardModel.transation.GROUP_MASTER_ID = blogId;
dashboardModel.transation.GROUP_NAME = "MIC";
dashboardModel.directoryMaster = (db.DIRECTORY_MASTER.Include(d => d.CATEGORY_MASTER).Include(d => d.REPRESENTATIVE_MASTER)).ToList();
return View(dashboardModel);
}
}
I would recommend strongly typing your MVC view to take a model of the type you require, and pass that model to the view via an argument in the return function of your controller's action method.

Categories