How to Create multiple Rows at once? - c#

How do I create multiple rows on my table at once?
I want to be able to add non-existent rows, and edit/update existing rows whenever I press submit.
To test this I only created 2 fields in the database, and cannot seem to add more than one row.
Value of numofbuilding = 5.
Only one row is inserted.
Tried:
public ActionResult CreateBuildings(Guid pi, int? numofbuilding)
{
OnboardModel model = new OnboardModel();
List<onboard_BuildingInfo> coms = new List<onboard_BuildingInfo>();
for (int i = 1; i <= (numofbuilding+1); i++)
{
onboard_BuildingInfo f = new onboard_BuildingInfo
{
projectID = pi,
building_ID = i
};
coms.Add(f);
}
context.onboard_BuildingInfos.InsertAllOnSubmit(coms);
context.SubmitChanges();
return View(model);
}
and tried:
public ActionResult CreateBuildings(Guid pi, int? numofbuilding)
{
OnboardModel model = new OnboardModel();
for (int i = 1; i <= numofbuilding; i++)
{
onboard_BuildingInfo coms = new onboard_BuildingInfo
{
projectID = pi,
building_ID = i
};
context.onboard_BuildingInfos.InsertOnSubmit(coms);
context.SubmitChanges();
}
return View(model);
}
BuildingInfo-Table
Create Table onboard_BuildingInfo (
projectID UNIQUEIDENTIFIER DEFAULT NEWID() ,
building_ID int NULL ,
city_building varchar(500) NULL ,
numberofcommon INT NULL
PRIMARY KEY (projectID)
)

Make the projectID not a primary key, or have a composite key on projectID and building_ID. Primary keys must be unique therefore you cannot have duplicate items in the projectID column. A composite key would mean that the combination of (projectID * building_ID) must be unique therefore you may have duplicates in either column, but not both.

Related

How I add same value in 2 rows using primary key in .Net Core

I have database table like this:
[Id] INT IDENTITY (1, 1) NOT NULL,
[SecondId] INT NOT NULL,
I want to add same value in [SecondId] of second row using [Id] along first row when I create new rows like
1 1 (first raw)
2 1 (second raw) [id is different, but secondId is same]
3 3 (first raw)
4 3 (second raw) [id is different, but secondId is same]
I hope this action be caused when I add new rows using HttpPost
Would you help me please??
In summary:
I want to create 2 rows when I use HttpPost
second row's [secondId] has same value with first row's [id]
Here's a method that may help you out with the logic part of your question. It takes a list of items that have a PrimaryId and a SecondaryId and will return to you the next item that should be added to that list.
First, here's the Item class we're using:
public class Item
{
public int PrimaryId { get; set; }
public int SecondaryId { get; set; }
}
The method figures out what to assign to the PrimaryId and SecondaryId of the next item by looking at the last item in the list (lastItem). It then creates a new item with a PrimaryId that is lastItem.PrimaryId + 1, and it assigns a SecondaryId based on whether or not lastItem.PrimaryId is odd or even.
Notice that if the previous item's PrimaryId is even, then the next item's SecondaryId is equal to the previous item's PrimaryId + 1. Otherwise it's equal to the previous item's PrimaryId.
Here's the method:
public static Item GetNextItem(List<Item> items)
{
// If there are no existing items, return the default first item
if (items == null || items.Count == 0)
{
return new Item {PrimaryId = 1, SecondaryId = 1};
}
// Otherwise, grab the last item in the list
var lastItem = items[items.Count - 1];
// And use it's PrimaryId to determine the values for the next item's properties
return new Item
{
PrimaryId = lastItem.PrimaryId + 1,
SecondaryId = lastItem.PrimaryId % 2 == 0
? lastItem.PrimaryId + 1
: lastItem.PrimaryId
};
}
And here it is in use:
private static void Main()
{
var items = new List<Item>();
// Populate the list of items using our method to continually get the next item
for (int i = 0; i < 4; i++)
{
items.Add(GetNextItem(items));
}
// Now output the items to the Console window
foreach (var item in items)
{
Console.WriteLine($"{item.PrimaryId} {item.SecondaryId}");
}
GetKeyFromUser("\nDone! Press any key to exit...");
}
Output

I just want to have an auto generated User Id with 7 digit number

Just want to ask how will i make an auto generated account number without changing its type to auto number in my database..
here is my previous code for making an Id with character:
private void AutoIncrementID()
{
int rowCount, userID1;
string userID;
rowCount = dtgGuest.Rows.Count;
userID = (dtgGuest.Rows[rowCount-1].Cells[0] .Value.ToString().Substring(1));
userID1 = int.Parse(userID);
userID1 = userID1+ 1;
txtAcctNo.Text = "A" + userID1.ToString();
}

can we use AddOrUpdate in Entity Framework to update only specific value in table if it exists for a key else Add new row/entry into the table?

I have a table
-------------
ID - CTypeID - ServiceID - CKey - CValue -
CEntity consists of -----
ID (Guid) - CTypeID (Guid) - ServiceID (Guid) - CKey (string) - CValue (string)
currently i am using
public int SaveConfig(Guid serviceId, Guid TypeId, NameValueCollection cCollection)
{
int result = 0;
var configurationEntities = cCollection.AllKeys.SelectMany( cCollection.GetValues, (ck, cv) => new CEntity()
{
CTypeId = TypeId,
CKey = ck,
CValue = cv,
ServiceId = serviceId
}).ToList();
using (var context = new CDataContext(_connectionString))
{
foreach (var cEntity in cEntities)
{
context.CEntities.AddOrUpdate(entry => new { entry.ServiceId, entry.CTypeId, entry.CKey }, cEntity);
}
result = context.SaveChanges();
}
return result;
}
the above code is making a new entry of cEntity into the table
with ID as empty guid.
in the above code I want to fetch for existing entry against ServiceId , TypeID & CKey if entry Exists it should update the CValue for CKey from cEntity where I am passing the ServiceId, TypeID & CKey.
And if no entry is found it should add new row with values in CEntity into table where ID should be newly generated.
Any Suggestions ??
using (var context = new CDataContext(_connectionString))
{
foreach (var cEntity in cEntities)
{
var entity = context.CEntities.FirstOrDefault(x => x.ServiceId == cEntity.ServiceId && x.TypeID == cEntity.TypeID && x.CKey == cEntity.CKey);
if(entity == null)
context.CEntities.Add(cEntity);
else
{
entity.CValue = cEntity.CValue;
entity.CKey = cEntity.CKey;
}
}
result = context.SaveChanges();
}

Assign Values to object properties by Id

I have a global list of objects used to hold values, values along with the Ids will be parsed into the ObjectManager function, the Ids can only ever be what is stated in the list. I want the function to update the value that corresponds to the Id.
Initially I tried to use a foreach loop which wasn't updating the objects in the list. Using the below code does update the objects in the list, but it only checks for the id that's parsed in, I am now trying this with a switch statement, early days.
What is the best way of achieving what I'm trying to do?
Sample Code:
public List<Object> obj = new List<Object>
{
new Object { id = 4, val = 20 },
new Object { id = 1, val = 34 },
new Object { id = 16, val = 27 },
new Object { id = 9, val = 36 }
};
public void ObjectManager(List<Object> myobj, int id, int val)
{
int i = 0;
int j = 0;
while (i < myobj.Count)
{
if(myobj[i].id == id)
{
j = myobj[i].val;
myobj[i].val = j + val;
}
}
}
You can select the item that you want to update using FirstOrDefault()
var variable = myobj.FirstOrDefault(o=>o.id = "YOUR_ID"
FirstOrDefault() returns null if the item is not found, so we need to check for null before updating the item
if (variable != null) variable.val = YOUR_VALUE
You should use Dictionary for this.
You'll find many solutions related add or update in Dictionary. like this or this

Improving performance of SQL SELECT in C#

I need some advice regarding updating a large number of records in a MySql database. I am currently storing a large number of words and their suffixes (a suffix array) into a database which results in a row count of approximately 4.3 million. Each record contains the primary key id, the actual word word, the document the word is in document, the offset of the word within the document 'offset', a flag which determines whether the record is a whole word or not flag and a link to the next record with the same value for word. Each record is initialized with a link value of -1.
This is my current code for updating the links in the database:
public void Link(object c)
{
DBConnection conn = (DBConnection)c;
rowcount = conn.GetRowCount();
string word;
int link;
List<Record> recordsList = new List<Record>();
List<Record> recordsMatched = new List<Record>();
for (int i = 0; i < rowcount; i++)
{
recordsList.AddRange(conn.ReadQuery("SELECT * FROM csa2018.words WHERE id = " + i));
word = recordsList[0].Word;
link = recordsList[0].Link;
recordsMatched = conn.ReadQuery("SELECT * FROM csa2018.words WHERE word = '" + word + "'");
for(int j = 0; j < recordsMatched.Count-1; j++)
{
if (recordsMatched[j].Link == -1)
{
conn.WriteQuery("UPDATE csa2018.words SET link = " + recordsMatched[j + 1].Id + " WHERE id = " + recordsMatched[j].Id);
}
else
{
break;
}
linkedRecords++;
}
linkedRecords++;
recordsMatched.Clear();
recordsList.Clear();
}
Form1.linkingFinished = true;
}
Overall, it has good performance when it finds words which are repeated frequently; however at around 60% the performance deteriorates because most of the remaining words are unique.
My guess is that this query:
recordsMatched = conn.ReadQuery(
"SELECT * FROM csa2018.words WHERE word = '" + word + "'");
shouldn't be like this because it is being called once for every row. Are there any better approaches like using stored procedures maybe?
P.S.: the ReadQuery method reads rows using the query supplied and constructs a Record object and adds each record to a List<Record>.
This is what my database looks like :
CREATE TABLE words ( id int(11) NOT NULL, word varchar(45) NOT NULL,
document varchar(45) NOT NULL, offset int(11) NOT NULL, flag int(11) NOT NULL,
link int(11) DEFAULT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
if I understand your code correctly than this single sql-statement should do the job:
UPDATE csa2018.words as w1
left join
(select w2.id as id, min(w3.id) as linked_to
from csa2018.words w2, csa2018.words w3
where w2.word = w3.word and
w3.id > w2.id limit 1) w4
on (w1.id = w4.id)
SET w1.link = IFNULL(w4.linked_to, -1)
The inner select-statement gives the mapping from one dataset to the linked dataset. You should watch the result of the select-statement to see if everthing is fine.

Categories