我有一个数据库类,其中包含以下方法:
方法的结果存储在私有数据集或数据表中.这些对象被定义为getter.
大约有10个类使用Database类.每个类都创建一个Database类的对象.现在我正在考虑使Database类保持静态.这是一个好主意吗?如果是这样,为什么?不,为什么不呢?
不确定我是否有正确的术语,但我对如何设置我的3层系统有点困惑.
假设我的数据库中有一个用户表.
在我的DAL中,我有一个UserDB类,它将存储过程调用到DB中以插入,更新,删除.我还有一个UserDetails类,在UserDB中用于返回和传入对象.
所以现在我不确定如何在我的业务逻辑层中使用它.我是否需要为用户提供另一个BLL对象类?如果是这样,这不是多余的吗?或者我只是在我的BLL中使用UserDetails类?
我在这里寻找指针和信息,我会做这个CW,因为我怀疑它没有一个正确答案.这是针对C#的,因此我将在下面对Linq进行一些引用.我也为这篇长篇大论道歉.让我在这里总结一下这个问题,然后是完整的问题.
简介:在UI/BLL/DAL/DB 4层应用程序中,如何更改用户界面,以显示更多列(例如在网格中),避免泄漏通过业务逻辑层进入数据访问层,掌握要显示的数据(假设它已经在数据库中).
让我们假设一个有3(4)层的分层应用程序:
在这种情况下,DAL负责构造SQL语句并对数据库执行它们,返回数据.
"正确"构建这样一个层的唯一方法就是总是"select*"吗?对我来说这是一个很大的禁忌,但让我解释为什么我在想.
让我们说,对于我的用户界面,我希望显示所有拥有活跃就业记录的员工."活跃"是指今天的就业记录包含今天(或者甚至是我可以在用户界面中设定的日期).
在这种情况下,假设我想向所有这些人发送一封电子邮件,因此我在BLL中有一些代码可以确保我还没有向同一个人发送过电子邮件,等等.
对于BLL,它需要最少量的数据.也许它调用数据访问层来获取活动员工列表,然后调用以获取它发送的电子邮件列表.然后它加入这些并构造一个新列表.也许这可以在数据访问层的帮助下完成,这并不重要.
重要的是,对于业务层,它实际上并不需要太多数据.也许它只需要每个员工的唯一标识符,对于两个列表,匹配,然后说"这些是活动的那些的唯一标识符,您还没有发送电子邮件到".然后构建DAL代码,构造只检索业务层需要的SQL语句吗?IE浏览器.只是"SELECT id FROM employees WHERE ..."?
那么我该怎么做用户界面呢?对于用户来说,这或许会是最好的,包括了很多信息,这取决于为什么我要发送电子邮件.例如,我可能想要包括一些基本的联系信息,或者他们工作的部门,或者他们的经理姓名等,而不是说我至少要显示姓名和电子邮件地址信息.
用户界面如何获取数据?我是否更改了DAL以确保将足够的数据返回给UI?我是否更改BLL以确保它为UI返回足够的数据?如果从DAL返回到BLL的对象或数据结构也可以发送到UI,那么BLL可能不需要进行太多的更改,但是UI的要求会影响超出应该与之通信的层. .如果这两个世界在不同的数据结构上运行,则可能必须对两者进行更改.
那么当UI被更改时,为了进一步帮助用户,通过添加更多列,我需要多深才能更改UI?(假设数据已存在于数据库中,因此不需要进行任何更改.)
提出的一个建议是使用Linq-To-SQL和IQueryable,这样如果DAL处理什么(如在什么类型的数据中)和为什么(如WHERE-clauses中)返回IQueryables,那么BLL可以可能会将这些内容返回到UI,然后可以构建一个Linq查询来检索所需的数据.然后,用户界面代码可以拉入所需的列.这将有效,因为使用IQuerables,UI最终会实际执行查询,然后它可以使用"select new {X,Y,Z}"来指定它需要的内容,甚至可以在必要时加入其他表.
这看起来很混乱.UI执行SQL代码本身,即使它已隐藏在Linq前端后面.
但是,为了实现这一点,不应该允许BLL或DAL关闭数据库连接,并且在IoC类型的世界中,DAL服务可能比UI代码所希望的更快地被处理掉,因此Linq查询可能最终会出现"无法访问已处置对象"的异常.
所以我正在寻找指针.我们有多远?你是怎么处理的?我认为UI的更改将通过BLL泄漏到DAL中是一个非常糟糕的解决方案,但是现在它看起来并不像我们能做得更好.
请告诉我我们有多愚蠢并证明我错了?
请注意,这是一个遗留系统.多年来,更改数据库模式的范围还不在范围内,因此使用ORM对象的解决方案基本上与"select*"相当,实际上并不是一种选择.我们有一些大型表格,我们希望避免在整个图层列表中提取.
c# business-logic data-access-layer isolation leaky-abstraction
我正在考虑以下列方式在2层WPF(或Windows窗体)应用程序中使用事务:
当我们打开新表格来编辑数据,在此交易中透明地编辑和保持更改时,我们可以开始新的交易.然后我们可以单击"确定"按钮并提交事务,或"取消"按钮并回滚它.如果我们想要打开另一个包含此数据的对话框窗口,我们可以使用嵌套事务.
问题是:这种使用交易的方式是否可以接受?我知道有很多不同的方法来实现这样的逻辑,但我想列出这个逻辑的优点和缺点.
我正在使用web2py为我的网站供电.我决定将web2py DAL用于在网站后面运行的长期运行程序.该程序似乎没有更新其数据或数据库(有时).
from gluon.sql import *
from gluon.sql import SQLDB
from locdb import *
# contains
# db = SQLDB("mysql://user/pw@localhost/mydb", pool_size=10)
# db.define_table('orders', Field('status', 'integer'), Field('item', 'string'),
# migrate='orders.table')
orderid = 20 # there is row with id == 20 in table orders
#when I do
db(db.orders.id==orderid).update(status=6703)
db.commit()
Run Code Online (Sandbox Code Playgroud)
它不会更新数据库,并且具有此ID的订单上的选择会显示正确的数据.在某些情况下,提交后的"db.rollback()"似乎有所帮助.
至少可以说很奇怪.你见过这个吗?更重要的是你知道解决方案吗?
更新:
更正:有问题的选择是在程序内完成的,而不是在程序之外.
有时,在进行一系列更新时,有些会在外面工作并且可用,而有些则无法使用.此外,一些查询将返回它最初返回的数据,即使数据在自原始查询后数据库中发生了更改.
我很想抛弃这种方法并转向另一种方法,任何建议?
我对整个n层体系结构都很陌生,我对使用MVVM和3层应用程序有一些疑问.
根据我的理解,我们有:
我的问题是,如何使用数据访问层将所有这些组合在一起?使用MVVM,我会让模型包含自己加载/更新的方法.相反,这应该是在WCF服务器上发生的事情?如果是这样,是否应将对服务器的引用存储在Model或ViewModel中?它应该怎么称呼?
我看到的每个存储库模式的例子都涉及一个非常简单的用例 - 一个对象类型和最基本的CRUD操作.然后,存储库经常直接插入MVC控制器.
真实世界的数据访问就是这样.真实世界的数据访问场景可能涉及对象的复杂图形和某种形式的事务包装器.例如,假设我要保存新订单.这涉及写入Order,OrderDetails,Invoice,User,History和ItemStock表.所有这一切都必须进行交易,承诺或回滚.通常我会传递IDbTransaction和IDbConnection之类的东西,并将整个操作捆绑在服务层中.
存储库模式在哪里适合?我错过了什么(也许是工作单位)?是否有比使用通常的固定博客片段更实际的存储库示例?
欣赏任何光线.
我正在使用ADO.NET 2.0和C#,Sql Server 2005设计数据访问层.我经常与大脑争论放置这些调用的位置.对于可维护的健壮代码,我应遵循以下哪种方式.
Public Class Company
{
public string CompanyId
{get;set;}
public string CompanyAddress
{get;set;}
public bool Create()
{
}
public bool Update()
{
}
public bool Delete()
{
}
}
Run Code Online (Sandbox Code Playgroud)
Public Class Company
{
public string CompanyId
{get;set;}
public string CompanyAddress
{get;set;}
}
Run Code Online (Sandbox Code Playgroud)
我会使用下面的另一个类来进行核心数据访问.如下
Public Class CompanyRepository
{
public Company CreateCompany(string companyId,string companyDescription)
{
}
public bool UpdateCompany(Company updateCompany)
{
}
public bool DeleteCompany(string companyId)
{
}
public List<Company> FindById(string id)
{
}
}
Run Code Online (Sandbox Code Playgroud) 目前我正在使用sqlite构建一个Windows应用程序.在数据库中有一个表说User,在我的代码中有一个Repository<User>和一个UserManager.我认为这是一个非常常见的设计.在存储库中有一个List方法:
//Repository<User> class
public List<User> List(where, orderby, topN parameters and etc)
{
//query and return
}
Run Code Online (Sandbox Code Playgroud)
这带来了一个问题,如果我想做一些复杂的事情UserManager.cs:
//UserManager.cs
public List<User> ListUsersWithBankAccounts()
{
var userRep = new UserRepository();
var bankRep = new BankAccountRepository();
var result = //do something complex, say "I want the users live in NY
//and have at least two bank accounts in the system
}
Run Code Online (Sandbox Code Playgroud)
你可以看到,返回List<User>会带来性能问题,因为查询的执行时间早于预期.现在我需要将其更改为IQueryable<T>:
//Repository<User> class
public TableQuery<User> List(where, orderby, topN parameters …Run Code Online (Sandbox Code Playgroud) 我一直在一些小项目中使用Realm,我非常喜欢它.我希望继续在更大的项目中使用它,我正在寻找更好的结构我的数据访问层.
我遇到了这个类似的问题,并试图建立我在那里找到的信息.在那里讨论的方法是DAO模式,所以我给了它一个镜头.
这是我的模特课.
class Chat: Object {
dynamic var id: String = ""
dynamic var createdAt: Date = Date()
dynamic var creatorId: String = ""
dynamic var title: String?
let chatMessages = List<ChatMessage>()
override static func primaryKey() -> String? {
return "id"
}
convenience init(fromJSON json: JSON) {
self.init()
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
然后我创建了一个包含ChatDAOProtocol所有方便助手方法.
protocol ChatDAOProtocol {
func addMessage(_ message: ChatMessage)
func getChatThumbnail() -> UIImage
func getParticipants(includingMe: Bool) -> [Participant]?
static func getChat(fromId id: String) -> …Run Code Online (Sandbox Code Playgroud)