I am developing an mvc App using Code First Approach. I want to generate VarcharID Based on the Identity Column Value. I know How to Achieve this in SQL. I want to Know how can I write the following SQL Query in VoidUp() Method
SQL Query I want to Write
CREATE TABLE [dbo].[EmployeeMaster](
[ID] [int] IDENTITY(1,1) NOT NULL,
[PreFix] [varchar](50) NOT NULL,
[EmployeeNo] AS ([PreFix]+ RIGHT('0000000' + CAST(Id AS VARCHAR(7)), 7)) PERSISTED,
[EmployeeName] VARCHAR(50),
CONSTRAINT [PK_AutoInc] PRIMARY KEY ([ID] ASC)
)
My Code in Migration.cs Void Up method
CreateTable(
"dbo.Employees",
c => new
{
ID = c.Int(nullable: false, identity: true),
EmployeePrefix = c.String(),
EmployeeEmpNo = c.String(), // Want to Change stuff Here
EmployeeName = c.String(nullable: false),
})
.PrimaryKey(t => t.ID);
You can write the data you need in "Seed" method of "Configuration.cs" file. You can find an example here. Your code will look smth like this:
foreach (var entity in context.EmployeeMaster.Where(em => string.IsNullOrEmpty(em.EmployeeNo))
{
var idStr = "0000000" + entity.Id.ToString();
entity.EmployeeNo = entity.Prefix + idStr.SubString(idStr.Length - 7);
}
context.SaveChanges();
Hope it will help you.
Related
I have a table and I fill one of the columns with a trigger if it is null or empty. I want to delete the trigger and do its job in code.
Do I have to first insert and after update or is there a better way?
In .NET Framework, ORM is NHibernate
CREATE TABLE [dbo].[Table]
(
[Id] INT NOT NULL PRIMARY KEY,
[Col1] NVARCHAR(50) NOT NULL,
[Col2] NVARCHAR(50) NOT NULL,
[Code] NVARCHAR(100) NULL
);
CREATE TRIGGER Update_Table
ON [dbo].[Table]
AFTER INSERT
AS
BEGIN
DECLARE #id INT
SELECT #id = Id
FROM inserted
UPDATE [dbo].[Table]
SET Code = 'CODE' + Id
FROM [dbo].[Table]
WHERE Id = #id AND Code IS NULL
END
I did this
Table entity = new Table() { Col1 = "aaa", Col2 = "bbb" };
entity = _repo.insert(entity);
entity.Code = "CODE" + entity.Id;
_repo.Update(entity);
sometimes i do not need update. Because users send this column value.
Table entity = new Table() { Col1 = "aaa", Col2 = "bbb", Code = "ccc" };
entity = _repo.insert(entity);
I tried insert then update. It is OK. Just seeking a better way.
I would simplify it by making CODE computed column, like this
CREATE TABLE [dbo].[Table]
(
[Id] INT NOT NULL PRIMARY KEY,
[Col1] NVARCHAR(50) NOT NULL,
[Col2] NVARCHAR(50) NOT NULL,
[Code] AS 'Code' + CAST(Id as NVARCHAR)
)
so, when inserting data, Code will be populated automatically
Notwithstanding Nino's answer, an interceptor is common way to achieve this.
Update:
It appears that event listeners are also an applicable technique too: https://stackoverflow.com/a/867356/1162077
You don't say how you're generating the entity id when it's not supplied by, so the event you intercept/handle will depend on how you're doing that.
I have a table with below columns.
CREATE TABLE [dbo].[tbl_QuizQue](
[id] [int] IDENTITY(1,1) NOT NULL,
[question] [nvarchar](max) NOT NULL,
[opt1] [nvarchar](50) NOT NULL,
[opt2] [nvarchar](50) NOT NULL,
[opt3] [nvarchar](50) NOT NULL,
[ans] [nvarchar](50) NOT NULL
)
I am trying to get a random record from this table, but only specific columns Like id, question, opt1, opt2, opt3. Present I am getting random record but it is fetching all columns. I tried below code for fetching a record with specific columns
dbUserEntities obj = new dbUserEntities();
// GET api/values
public IEnumerable<tbl_QuizQue> Get()
{
var result = obj.tbl_QuizQue.OrderBy(r => Guid.NewGuid()).Select(o => new { o.id, o.question, o.opt1, o.opt2, o.opt3 });
return result;
}
Here, i am getting below error while return result;
Cannot implicitly convert type 'System.Linq.IQueryable<AnonymousType#1>' to
'System.Collections.Generic.IEnumerable<studentQuiz.tbl_QuizQue>'. An explicit conversion exists (are you missing a cast?)
Help me where I am doing wrong.
I'd do this:
public IEnumerable<tbl_QuizQue> Get()
{
var result = obj.tbl_QuizQue.OrderBy(r => Guid.NewGuid())
.Select(o => new { o.id, o.question, o.opt1, o.opt2, o.opt3 })
.AsEnumerable()
.Select(q => new tblQuizQue {q.id, q.question, q.opt1, q.opt2, q.opt3);
return result;
}
By first getting back just the columns you are interested in, you can constrain the query. You can then map them into the object you are interested in.
Change the return type of the Get function to
IEnumerable<dynamic>
and your code will execute.
As for whether it's a good idea, I guess you have to defer to the customs of the c# tribe.
I'd be tempted to use it all the time.
Here I have a migration of CodeFirst using EF6
public override void Up()
{
CreateTable(
"dbo.MyTable",
c => new
{
Id = c.Int(nullable: false, identity: true),
Date = c.DateTime(nullable: false, defaultValueSql: "GETUTCDATE()"),
})
.PrimaryKey(t => t.Id);
}
But we found that the Date could not be customized at insert. So we need a migration to delete the defaultValueSql parameter on Date column.
I've tried using AlterColumn without defaultValueSql parameter,
public override void Up()
{
AlterColumn("dbo.MyTable", "Date", c => c.DateTime(nullable: false));
}
public override void Down()
{
AlterColumn("dbo.MyTable", "Date", c => c.DateTime(nullable: false, defaultValueSql: "GETUTCDATE()"));
}
it works neither for inserting and updating the Date, nor to the definition of table.
CREATE TABLE [dbo].[MyTable] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Date] DATETIME DEFAULT (getutcdate()) NOT NULL,
);
Anyone has run into this situation, please ?
Actually, in the database, there was a Constraint created for the defaultValueSql, and I think this parameter works by the sys table, rather than MyTable, which results in ineffective of my AlterColumn.
Eventually, I created some original SQL commands for my purpose like following:
public override void Up()
{
Sql(#"
DECLARE #sql NVARCHAR(MAX)
SELECT #sql = N'alter table [EffectiveDonations] drop constraint ['+d.name+N']'
FROM sys.default_constraints
WHERE d.parent_object_id = OBJECT_ID(N'MyTable')
AND col_name(parent_object_id, parent_column_id) = N'Date'
EXEC (#sql)
");
Sql("PRINT 'Information: delete [defaultvaluesql]';");
}
public override void Down()
{
Sql(#"ALTER TABLE [MyTable] ADD DEFAULT getutcdate() FOR [Date]");
Sql("PRINT 'Information: create [defaultvaluesql] for column [Date] of table [MyTable]';");
}
Share to hope this could be help to others.
Try it in two stages:
public override void Up()
{
AlterColumn("dbo.MyTable", "Date", c => c.DateTime(nullable: true,
defaultValue: "NULL"));
AlterColumn("dbo.MyTable", "Date", c => c.DateTime(nullable: false));
}
I am trying to join a table (db.Students) within this query to get firstname and lastname included in the query by joining on the StudentID. How do I do this? I've come up with about 50 queries that don't work and one that only gives me half of what I want. This is what I have so far that is working.
var gradeaverages = db.Grades
.Where(r => r.StudentID == r.StudentID)
.GroupBy(g => g.StudentID, r => r.Grades)
.Select(g => new
{
StudentID = g.Key,
Rating = g.Average()
});
var data = gradeaverages.ToList();
dataGridView1.DataSource = data;
It does have a foreign key. Here is the constraint:
CONSTRAINT [FK_Grades_Students] FOREIGN KEY ([StudentID]) REFERENCES [dbo].[Students] ([StudentID])
Here are my tables:
CREATE TABLE [dbo].[Grades] (
[GradeID] INT NOT NULL,
[StudentID] INT NOT NULL,
[Date] NCHAR (10) NULL,
[Grades] DECIMAL (18) NULL,
PRIMARY KEY CLUSTERED ([GradeID] ASC),
CONSTRAINT [FK_Grades_Students] FOREIGN KEY ([StudentID]) REFERENCES [dbo].[Students] ([StudentID])
CREATE TABLE [dbo].[Students] (
[StudentID] INT NOT NULL,
[First Name] NVARCHAR (40) NOT NULL,
[Last Name] NVARCHAR (40) NOT NULL,
[Phone] NVARCHAR (24) NULL,
CONSTRAINT [PK_Table] PRIMARY KEY CLUSTERED ([StudentID] ASC)
I'm looking for an out put of
StudentID FirstName LastName AverageGrade (according to StudentID I assume)
Actually there is not enough information about db structure, but I guess your query might look like this:
var data = db.Students.Include("Grades")
.Select(x => new
{
StudentId = x.StudentId,
Rate = x.Grades.Avg(y => y.Mark)
})
.ToList();
This .Where(r => r.StudentID == r.StudentID) is meaningless, because you compare some value with itself.
Or like this
var data = db.Grades
.GroupBy(x => x.StudentId)
.Select(x => new
{
StudentId = x.Key,
Rate = x.Avg(y => y.Mark)
})
.ToList();
I have created the EF model and then in a Class I have written the following Code to retrieve the value form the DataBase. And store the value in another Table. But it gives me the Error "DATAREADER IS INCompatable" as explained Below..
EmpRole empr = new EmpRole();
empr.EmpId = strEmpId;
string str="select RoleId from RoleName where roleName like '"+strDesignation+"'";
var context= DbAccess.Data.ExecuteStoreQuery<RoleName>(str, null); //Here Showing Error
empr.RoleId = Convert.ToInt16(context);
DbAccess.Data.EmpRoles.AddObject(empr);
DbAccess.Commit();
It's showing the error like:
DataTables were:
CREATE TABLE [dbo].[RoleName](
[SNo] [int] IDENTITY(1,1) NOT NULL,
[RoleId] [smallint] NOT NULL,
[RoleName] [varchar](50) NULL,
CONSTRAINT [PK_RoleName] PRIMARY KEY CLUSTERED
(
[RoleId] ASC
)
CREATE TABLE [dbo].[EmpRoles](
[Sno] [int] IDENTITY(1,1) NOT NULL,
[EmpId] [varchar](8) NOT NULL,
[RoleId] [smallint] NOT NULL,
[ReportingToId] [varchar](8) NULL,
CONSTRAINT [PK_EmpRoles] PRIMARY KEY CLUSTERED
(
[Sno] ASC
)
The data reader is incompatible with the specified 'MyOrgDBModel.RoleName'. A member of the type, 'SNo', does not have a corresponding column in the data reader with the same name.
Please tell me the reasons what to do to execute the sqlQuery.
This is because you are not selecting the SNo column in your select query. As you are populating in RoleName and it has property SNo column should be present in data reader. If you just want the RoleId to be in query then create new type with one property RoleId and use this. Create new type like below
public class CustomRoleName
{
int RoleId { get; set; }
}
Now change your code as follow
EmpRole empr = new EmpRole();
empr.EmpId = strEmpId;
string str="select RoleId from RoleName where roleName like '"+strDesignation+"'";
foreach(CustomRoleName rn in DbAccess.Data.ExecuteStoreQuery<CustomRoleName>(str))
{
empr.RoleId = rn.RoleId ;
DbAccess.Data.EmpRoles.AddObject(empr);
DbAccess.Commit();
break;
}